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
- Anonymous
October 03, 2005
Why does the error happen only if the replicate("_") is greater than 100 characters? - Anonymous
October 03, 2005
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. - Anonymous
October 03, 2005
Hooray! Thanks, Calvin!