Technicalia
|
Note that the formal language definition places no constraint on the order of evaluation of elements. Consider the fragment:
integer x
function add1tox() x+=1 return x end function
x = 3
s = {x,add1tox()}
A compiler implementation(/version) may notice that x is definitely 3 and choose to use (/push) a literal 3 for the first element of s,
or it may just use the content (/address) of x. Hence s could become {3,4} or {4,4}, and that may well depend on non-obvious things,
such as whether there are any outstanding forward calls. With s = {x,add1tox(),x,add1tox()}, the result could be any of {3,4,3,5},
{3,4,4,5}, {3,4,5,5} or {5,4,5,5}, or even {3,5,3,4}, {3,5,5,4} or {5,5,5,4}. I believe the current version always yields {5,4,5,5},
but I would not bet one cent on that. It is ambiguous code, that utterly fails to communicate precise intent, bearing in mind that
side effects may be buried deep inside a complex function, not actually intended at all, hence the compiler (and you) should treat
such code with appropriate contempt.
You should never attempt to modify the same thing twice in one statement, and likewise you should
never both modify and reference the same thing in the same statement, ever (in any programming language).
In some cases the compiler may issue "warning: suspect evaluation order" or similar, but there is certainly no guarantee of that.
TIP: you can get rid of that warning by making copies of any file-level variables in local variables beforehand, or moving the
function call outside the sequence creation statement, eg/ie
integer x
procedure p()
-- sequence s = {x,add1tox()} -- -- warning
integer lx = x -- ++ no
sequence s = {lx,add1tox()} -- ++ warning
--or--
integer newx = add1tox() -- ++ no
sequence s = {x,newx} -- ++ warning
--or--
integer oldx = x -- ++ also
integer newx = add1tox() -- ++ no
sequence s = {oldx,newx} -- ++ warning
The intention of creating {3,4} or {4,4} then becomes absolutely clear and beyond any doubt.
|