String Optimization: More detail


In the prior post (String Optimization. How does it work?) I described an optimization of how the Assignment statement calls the expression evaluator for string concatenation statements.  There are certain limitations with this optimization. For example, if you use a Public variable and call a routine that can modify the variable, you might get unexpected results.


 


            MyPublicVar = MyPublicVar + MyRoutine(MyPublicVar)


 


Another example is passing the variable by reference:


            MyVar = MyVar + MyRoutine(@MyVar)


 


This kind code is very hard to read and does not seem deterministic. Also, in C++, you can write identical constructs, which have undefined meaning.


 


A legitimate case is recursion. Over the last 8 years, we’ve had very few reports of customers running into this problem.


 


Try running the code below, and you’ll get 2 different results.


Why?


The optimization modifies the compiled code to evaluate the addend:


 


            x = x + <something recursive>


is modified to be


            x = “” + <something recursive>


and then the result is evaluated.


The recursive call will see only the modified code, which doesn’t do the append of the addend.


 


There are several easy workarounds:


            y=<something recursive>


            x = x + y


or


            x = “” + x + <something recursive>


 


This has been fixed for the next release.


 


 


 


 


ndepth=3


cResult=recur(ndepth,.t.)


?”Opt=.t. Len=”+TRANSFORM(LEN(cResult)),”Result=”,cResult


?”Now doing valid res”


cResult=recur(ndepth,.f.)


?”Opt=.f. Len=”+TRANSFORM(LEN(cResult)),”Result=”,cResult


 


PROCEDURE recur(nLev,fOpt) as String


      LOCAL cstr,i


      IF nlev=1


            RETURN “1”


      ENDIF


      cstr=REPLICATE(“_”,110)


      IF fOpt


            cstr=   cstr+TRANSFORM(nLev)+”  “+recur(nLev-1,fOpt)


      ELSE


            cstr=””+cstr+TRANSFORM(nLev)+”  “+recur(nLev-1,fOpt)


      ENDIF


      ?nlev,”L=”+TRANSFORM(LEN(cstr)),cstr


      RETURN cstr


 

Comments (3)

  1. Michel Roy says:

    Why does the error happen only if the replicate("_") is greater than 100 characters?

  2. CalvinH says:

    The optimization code does not run until the string length is > 100 chars. The overhead of executing all the extra code isn’t necessary for short strings.

Skip to main content