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

Reply via email to