On 12.02.2017 16:11, Mauro Zallocco wrote:
Hi all.
I tried this:
groovy -version
Groovy Version: 2.4.6 JVM: 1.8.0_66 Vendor: Oracle Corporation OS: Windows 7
int i = 0
++(++(++i));
assert i == 1
However with C++, it gives 3.
It took me a while, but I think I start to get an idea why this happens.
"++i" is recognized by the compiler as it should be. But it is legal in
Groovy to do ++1 for example. Of course we will not change the value of
the literal 1 here. This is just to show that there is such a logic
applying to any expression. In that sense (++i) will return a value and
then we do ++ on that value to do it again on the result. The outer two
cases do not involve a local variable. Or let me write this a little bit
different:
++i is expanded to:
tmp = i.next()
i = tmp
return tmp
"++(++i)" is:
tmp = i.next()
i = tmp
return ++tmp
which is:
tmp = i.next()
i = tmp
tmp2 = tmp.next()
return tmp2
and that is because during code generation we work from inside out and
do not return any expression.
If had this implemented in a macro manner we would probably have done
something like this:
++i is expanded to (i = i+1)
++(++i) is expanded to ++(i=i+1) with the rule of ++ only applying to
the local variable on the RHS we expand then to i=i+1+1.
Then of course ++(++(++i)) is i=i+1+1+1, with the compiler most probably
shortening this to i=i+3
But as I said, we do not do it in a macro manner, instead we work with
the result of an expression and the result of i=i.next() is the value of
RHS, thus whatever i.next() returns. There is no chance to increase the
value in the local variable here.
Options:
(1) do nothing and explain the difference only
(2) do allow these post- and prefix operators only on
VariableExpressions, making the code above no longer compile
(3) do special casing
(4) combine 2 and 3 to require a VariableExpression as innermost
expression and allow only prefix or postfix operators outside
Since (3) will include (1) to some extend my feeling here is, that this
is no good idea at all. (1) is surely underdocumented atm. But the real
question is if we should go with 1,2 or 4. And preferred solution is to
go with 2. Anyone able to think of a really really good reason not to?
bye Jochen