Processing of increment and decrement operators in Java
Dear all,
I currently notices something about increment and decrement operator
From the Java operator precedence table ++ has a higher precedence than +. But this doe not seem to be the situation in for real.
In C programming:
int x = 5;
int y = x + ++x;
==> y will be assigned 12
In Java, its different
int x = 5;
int y = x + ++5;
==> y will be assigned 11.
However,
int x = 5;
int y = ++x + x;
==> y =12
Re: Processing of increment and decrement operators in Java
Hello fredyeboah!
For your next posts you should choose the appropriate forum to start a new thread. I don't want to be pedantic, I'm just saying that because a moderator will probably move your thread from the "member introductions" section.
Quote:
Originally Posted by
fredyeboah
From the Java operator precedence table ++ has a higher precedence than +. But this doe not seem to be the situation in for real.
Why are you saying that? The examples you posted prove the above statement.
You need to see the value of x in both examples.
Code java:
int x = 5;
int y = x + ++5; //++5 is the first statement that is executed and the result is (5+1) = 6. x is still 5.
//And then the addition is executed: x + (the result of the first statement which is 6) = 5+6 =11
Code java:
int x = 5;
int y = ++x + x; // ++x is the first that is executed and the result is (5+1) = 6. So now x = 6. And then the addition is executed: x + x = 6 + 6 = 12
Hope this helps.
Processing of increment and decrement operators in Java
I currently notices something about increment and decrement operator
From the Java operator precedence table ++ has a higher precedence than +. But this doe not seem to be the situation in for real.
In C programming:
int x = 5;
int y = x + ++x;
==> y will be assigned 12
In Java, its different
int x = 5;
int y = x + ++x;
==> y will be assigned 11.
However,
int x = 5;
int y = ++x + x;
==> y =12
Edit / Delete Edit Post Quick reply to this message Reply Reply With Quote Reply With Quote Multi-Quote This Message
Re: Processing of increment and decrement operators in Java
Hi Andreas,
Do you mean to say that ++5 will become 6 in Java?
Re: Processing of increment and decrement operators in Java
Quote:
Originally Posted by
fredyeboah
Hi Andreas,
Do you mean to say that ++5 will become 6 in Java?
No, my bad. ++x will become 6 in the above code. ++5 will cause an error.
Re: Processing of increment and decrement operators in Java
In addition to posting in the correct forum, please do not post multiple copies of the same question in different forums. I've merged your identical threads.
Re: Processing of increment and decrement operators in Java
Re: Processing of increment and decrement operators in Java
Quote:
Originally Posted by
fredyeboah
Dear all,
From the Java operator precedence table ++ has a higher precedence than +. But this doe not seem to be the situation in for real.
Au contraire.
From the Java Language Specification (You have read all of it, right? The Third Edition has only 684 pages.)
Quote:
15.7 Evaluation Order
The Java programming language guarantees that the operands of operators appear
to be evaluated in a specific evaluation order, namely, from left to right.
It is recommended that code not rely crucially on this specification. Code is
usually clearer when each expression contains at most one side effect, as its
outermost operation, and when code does not depend on exactly which exception
arises as a consequence of the left-to-right evaluation of expressions.
15.7.1 Evaluate Left-Hand Operand First
The left-hand operand of a binary operator appears to be fully evaluated before
any part of the right-hand operand is evaluated."
So, in your example, the value of the expression is "accumulated" by first getting the value of x from memory. (The value of x in memory has not been changed at this point in the evaluation.)
Then, the accumulator sees a binary '+' operator and looks at the right-hand part of the expression: ++x is implemented (that is, the value of x in memory is fetched and incremented and the value is stored back in memory). The incremented value is added to the previously accumulated partial value of the expression. Finally, the result is stored in the memory location for y.
(Note that the actual sequence of machine operations may not look exactly like my description, but the result must be "as if" that were the case.)
Consider:
Code java:
public class TestExpression
{
public static void main(String [] args)
{
int x;
int y;
x = 5;
System.out.println("1: Original value of x is " + x);
y = x + ++x;
System.out.println(" After 'y = x + ++x': x = " + x + ", y = " + y);
System.out.println();
x = 5;
System.out.println("2: Original value of x is " + x);
y = ++x + x;
System.out.println(" After 'y = ++x + x': x = " + x + ", y = " + y);
System.out.println();
}
}
Output:
Code :
1: Original value of x is 5
After 'y = x + ++x': x = 6, y = 11
2: Original value of x is 5
After 'y = ++x + x': x = 6, y = 12
See how it goes? In the second part, going left-to-right, x is incremented in memory and the incremented value is placed into the partial value of the expression. Then the (just-incremented) value of x is fetched and this is added to the expression value.
In Java, these results are absolutely valid and guaranteed predictable according to the language specification.
On the other hand...
Now, in the C programming language definition documents (C++ too), it is expressly specified that the compiler is not (that's not) obligated to evaluate left-to-right or, in fact, in any particular order. That way the compiler is free to optimize its evaluation sequence any way it damn well pleases.
A given compiler might go left-to-right or right-to-left for any given expression, and other compilers might legitimately do it differently. The value of expressions like yours (where individual terms have side-effects that make the value dependent on which direction the compiler happens to choose for evaluation) is unpredictable.
According to the C and C++ language specification documents, evaluation of expressions like yours leads to undefined behavior. There is absolutely no reason to write that expression in a "real" C or C++ program (and an obvious reason not to), but beginners are often confused by the concept.
For C documentation, reference ISO/IEC 9899:1999(E)
Quote:
6.5 Expressions
.
.
.
Except as specified
later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation
of subexpressions and the order in which side effects take place are both unspecified.
Bottom line:
Java expressions are guaranteed to be evaluated left-to-right. Operator precedence comes into play when the compiler has to make a decision about which of two operators to apply first.
C (and C++) expressions are not guaranteed to be evaluated left-to-right except for the specific cases spelled in the language specification. Expressions involving operators with side-effects are dangerous if the same variable appears in the expression more than once. (There is a concept of "sequence point" that makes it very clear why your expression leads to an indeterminate result. You can look it up.)
The meaning of the phrase "undefined behavior" is spelled out very explicitly in the C and C++ specifications. Since this is a Java forum, not C or C++, I won't bore you (beyond what I have already done) with the details.
Cheers!
Z
Re: Processing of increment and decrement operators in Java
Hi Z,
Good to hear all these comments from you. Do you mean to say that Java evaluate expression from left-to-right irrespective of the operator precedence?. The main problem with the code I posed is how to explain operator precedence with x=5; int y = x + ++x;
Note:
if Java does not consider the (++x) first then what is the essence of (++) having a higher precedence over (+)?
Under what circumstance does the compiler make its choices? I thought operator precedence was to settle all these in all languages.
Re: Processing of increment and decrement operators in Java
Quote:
Originally Posted by
fredyeboah
Hi Z...Do you mean to say that Java evaluate expression from left-to-right irrespective of the operator precedence?.
I did not say that, and I certainly did not mean to say that. Please re-read the quoted section from the Java Language Specification. Here. I'll quote it again:
Quote:
The left-hand operand of a binary operator appears to be fully evaluated before
any part of the right-hand operand is evaluated.
Is there any question as to what that means? It has nothing (really: absolutely nothing) do do with operator precedence. Period. Full stop.
I can't think of a way to "explain" the sentence that I just re-quoted, but I will reword it a little less precisely but more specifically:
For an expression like "y = x + AnythingatAtAll" compiler plugs in the current value of x before it evaluates any part of the stuff on the right-hand side of the binary '+' operator. Period. Full stop.
Did you see the next sentence in my quote from the previous post:
Quote:
It is recommended that code not rely crucially on this specification. Code is
usually clearer when each expression contains at most one side effect, as its
outermost operation, and when code does not depend on exactly which exception
arises as a consequence of the left-to-right evaluation of expressions.
In other words: They recommend that you do not write expressions that depend on whether the evaluation is left-to-right or right-to-left. That's not just my recommendation. That's the recommendation of the Guys Who Wrote The Book.
So, for example,don't write code with stuff like "y = x + ++x or "y = x++ + ++x" or even "x = ++x'. These are all legal Java expressions, and the compiler will perform the operations in a prescribed manner, but we mere humans might get caught up in a frivolous debate about what we "think" it should do. Etc., etc., etc...
I mean, I tried to give an explanation consistent with the Java Language Specification (and consistent with the results from my test program that used that expression). It's not a Bad Thing to try to understand why it works the way it works, but I can't see much chance of my being able to explain why it doesn't work some other way that someone "thought" it should work.
I'm thinking that the reason the authors of the Java Language Specification felt the need to dis-recommend such expressions is because some people get confused because they don't know about (or can't understand) the simple declarative statement, "The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated."
Now, the reason that your original expression (as corrected in post #3 of this thread) depends on the left-to-right thing is that the variable x appears twice and there is an operation that has a side effect on x. Bottom line: For best understanding and code maintainability, it is recommended that you not put expressions like that in your code. (If a term involves a side effect on a variable, don't let that variable appear more than once in the expression.) Period. Full Stop.
Quote:
Originally Posted by fredyeboah
...what is the essence of (++) having a higher precedence over (+)?
For the expression "x + ++x", after the code has plugged in the original value of x into its expression evaluator (because x is on the left-hand side of the binary operator '+'), it looks at the right-hand side and decides what to do. The right-hand side of the binary '+' operator is '++x.' The code will increment the value of x in memory and then perform the '+' operation, adding the incremented value to the previous expression value.
Quote:
Originally Posted by fredyeboah
Under what circumstance does the compiler make its choices?
When the code gets around to evaluating any part of an expression, it applies rules of precedence.
Another quote from the Java Language Specification:
Quote:
15.7.3 Evaluation Respects Parentheses and Precedence
Java programming language implementations must respect the order of evaluation
as indicated explicitly by parentheses and implicitly by operator precedence.
Example 1:
If the expression is y = a + b*c, the code plugs in the value of a, then it looks at the right-hand side of the '+' operator. It sees "b*c" and has to know what to do next. Since the '*' operator has higher precedence than '+', the multiplication is performed and the product is added to the previous value of the expression.
Example 2:
If the expression is y = a * b + c, the code plugs in the value of a and then looks at the right-hand side of the '*' operator. It sees "b+c". Since the '+' operator has lower precedence than '*', the previous value of the expression is multiplied by b. Then the compiler looks on the right-hand side of the '+' operator and sees "c" It adds the value of c to the previous value of the expression.
That's how precedence rules are applied.
A final note: If you have way to examine machine language output from a compiler, you might see a sequence of operations that look a little different (or a lot different, depending on the compiler's optimization capabilities), but the code is required to perform as described in the Java Language Specification. That is the import of the word "appears" in the sentence "The left-hand operand of a binary operator appears to be fully evaluated..." The code can do anything it wants to as long as it satisfies the specified behavior.
Cheers!
Z