Let's look at the third line.
c = a * + a / a;
There is no postfix *
operator (EXPR*
), but there is an infix *
operator (EXPR * EXPR
): The multiplication operator. The *
must therefore be a multiplication operator.
There is a prefix +
operator (+EXPR
): The unary plus operator. The +
must therefore be a unary plus operator.
The above is equivalent to
c = (a * (+a)) / a;
(10 * (+a)) / a
(10 * (+10)) / a
(10 * 10) / a
100 / a
100 / 10
10
It's exactly the same situation for the EXPR * + EXPR
in the next line.
c = 5 + a * + a / a
is equivalent to
c = 5 + ((a * (+a)) / a)
5 + ((10 * (+a)) / a)
5 + ((10 * (+10)) / a)
5 + ((10 * 10) / a)
5 + (100 / a)
5 + (100 / 10)
5 + 10
15
It's exactly the same situation for the EXPR * + EXPR
in the last line.
c = ++a + a++ - --a - a-- + a * + a/a;
is equivalent to
c = ((((++a) + (a++)) - (--a)) - (a--)) + ((a * (+a)) / a);
The last line both uses and modifies a
in the same expression. In most languages, the behaviour of such code is undefined because the operand evaluation order is undefined. Even then, understanding when a reference is a placed on the stack as oppose to a copy is crucial, and that makes for poor code.
In Java, the order is defined, but it is not actually the case in my testing. Let's look at ((++a) + (a++)) - (--a)
with an initial value of 10
for a
.
Using left-to-right evaluation:
((++a) + (a++)) - (--a) [a=10]
(11 + (a++)) - (--a) [a=11]
(11 + 11) - (--a) [a=12]
22 - (--a) [a=12]
22 - 11 [a=11]
11
Using java
, you get 13. As such, I won't actually show how your last line is evaluated. That would require inspect the generated byte code, which goes to show it's awful code if it's even valid.