• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Tim Cooke
  • paul wheaton
Sheriffs:
  • Paul Clapham
  • Liutauras Vilda
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Piet Souris
  • Himai Minh
Bartenders:

understanding operator precedence and evaluation ?

 
Ranch Hand
Posts: 924
1
Netbeans IDE Fedora Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
please refer the link http://radio.javaranch.com/corey/2004/07/12/1089659625000.html. it has two examples given below :





i'm not able to understand the difference between operator precedence and evaluation. to be specific what does evaluation means. i understand that operands are first evaluated from left to right and then operator precedence is applied. but i'm not understanding what is evaluation with respect to both the examples. please explain how are operands got evaluated in both the examples and what does evaluation means ?

also the oracle tutorial given at http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html says that

Thee operators in the following table are listed according to precedence order. The closer to the top of the table an operator appears, the higher its precedence. Operators with higher precedence are evaluated before operators with relatively lower precedence. Operators on the same line have equal precedence. When operators of equal precedence appear in the same expression, a rule must govern which is evaluated first. All binary operators except for the assignment operators are evaluated from left to right; assignment operators are evaluated right to left.



this is opposite to what is writter in Corey's SCJP timeline. please help to remove my confusion ??
 
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

gurpeet singh wrote:



here space done the trick.

++a = 2(hence preincrement) and now a is 2 and a++ = 2(post increment) => 4

gurpeet singh wrote:



seriously, you need to delve in operator precedence chapter http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
 
Saloon Keeper
Posts: 14798
333
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

gurpeet singh wrote:i understand that operands are first evaluated from left to right and then operator precedence is applied.



No. Operator precedence is always determined first. This is necessary, because you won't even be able to evaluate an operation if you don't know what operands belong to what operators. As a matter of fact, operator precedence is determined at compile time, whereas evaluation is (obviously) done at runtime.

Evaluation simply means that the results of an expression is being computed. This always happens from left to right. I'll explain using your example.
Before the program is run at all, the compiler already determines how this expression needs to be evaluated. You can imagine this as if the compiler inserts parentheses to make it unambiguous what happens exactly:

++a and a++ get parentheses because they bind more tightly to 'a' and 'a' than the + operator does, because they have higher precedence. Then their respective results are passed to the + operator, because + has higher precedence than =.

So after the compiler is done, and the JVM runs the program, all that's left is evaluation. Precedence doesn't play a role anymore, because all the parentheses have already been inserted. Now, the fact that evaluation is done from left to right doesn't really matter for simple expressions. It only matters for conditional expressions or operations that have side effects. a++ is an example of an operation with a side effect, but don't forget about method calls!

Let's take a look at
You'd expect the last expression to evaluate to 5, with x becoming 5 and y becoming 3.
This however is not the case. This expression will evaluate to 4, with x becoming 4 and y becoming 3.

Why? Here's why:
 
gurpeet singh
Ranch Hand
Posts: 924
1
Netbeans IDE Fedora Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:

gurpeet singh wrote:i understand that operands are first evaluated from left to right and then operator precedence is applied.



No. Operator precedence is always determined first. This is necessary, because you won't even be able to evaluate an operation if you don't know what operands belong to what operators. As a matter of fact, operator precedence is determined at compile time, whereas evaluation is (obviously) done at runtime.

Evaluation simply means that the results of an expression is being computed. This always happens from left to right. I'll explain using your example.
Before the program is run at all, the compiler already determines how this expression needs to be evaluated. You can imagine this as if the compiler inserts parentheses to make it unambiguous what happens exactly:

++a and a++ get parentheses because they bind more tightly to 'a' and 'a' than the + operator does, because they have higher precedence. Then their respective results are passed to the + operator, because + has higher precedence than =.

So after the compiler is done, and the JVM runs the program, all that's left is evaluation. Precedence doesn't play a role anymore, because all the parentheses have already been inserted. Now, the fact that evaluation is done from left to right doesn't really matter for simple expressions. It only matters for conditional expressions or operations that have side effects. a++ is an example of an operation with a side effect, but don't forget about method calls!

Let's take a look at
You'd expect the last expression to evaluate to 5, with x becoming 5 and y becoming 3.
This however is not the case. This expression will evaluate to 4, with x becoming 4 and y becoming 3.

Why? Here's why:



Thanks Stephen. but still i have doubts. in your example you said "++a and a++ get parentheses because they bind more tightly to 'a' and 'a' than the + operator does, because they have higher precedence. Then their respective results are passed to the + operator, because + has higher precedence than =. ". among these two operations i.e. ++a and a++ , which will be evaluated first. as per javadocs operator precedence chart, post increment operators have higher precedence than pre increment , which means a++ will get evaluated first. but if you refer corey's scjp timeline, he says exactly opposite. he says that first operand evaluation will occur which is always from left to right. further he says, ++a will be evaluated . i'm really confused who is right and who is wrong.
 
Stephan van Hulst
Saloon Keeper
Posts: 14798
333
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

gurpeet singh wrote:as per javadocs operator precedence chart, post increment operators have higher precedence than pre increment , which means a++ will get evaluated first.



No. Precedence has nothing to do with order of evaluation. Precedence determines which operands bind to which operators. We have already determined that at compile time. Since in your example the pre- and post-increment operators don't compete over the same operand (they are both applied to a separate occurrence of 'a') the compiler doesn't even need to compare the two for priority. In your example, ++a gets evaluation before a++ because the first one is on the left, and Java evaluates from left to right. Precedence only comes into play if they compete over the same occurrence of an operand. For example: -a++;

In the above example, the expression will get evaluated (from left to right) as -(a++) because post-increment has higher precedence than negation. Operator precedence only determines *what* is evaluated, not *when* it is evaluated.
 
Greenhorn
Posts: 19
3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Stephan van Hulst wrote:
Let's take a look at
You'd expect the last expression to evaluate to 5, with x becoming 5 and y becoming 3.
This however is not the case. This expression will evaluate to 4, with x becoming 4 and y becoming 3.

Why? Here's why:



Even though this thread is a bit old it's probably worth supplementing the knowledge here with the JLS. It spells this out quite nicely IMHO (emphasis below is mine).

From https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.7.1


The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.

If the operator is a compound-assignment operator (§15.26.2), then evaluation of the left-hand operand includes both remembering the variable that the left-hand operand denotes and fetching and saving that variable's value for use in the implied binary operation.



There are some really good examples in §15.7 as well.
 
Greenhorn
Posts: 29
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I know it's an very old topic, but I didn't feel like I should open a new one, so I'll just ask here

I really don't have a problem with getting correct results, but there is one thing that does confuse me regarding precedence of prefix and postfix unary operators.

Stephan van Hulst wrote:

gurpeet singh wrote:as per javadocs operator precedence chart, post increment operators have higher precedence than pre increment , which means a++ will get evaluated first.



... Since in your example the pre- and post-increment operators don't compete over the same operand (they are both applied to a separate occurrence of 'a') the compiler doesn't even need to compare the two for priority.



When does higher priority of postfix operator have real impact on a result regarding prefix operator? I mean, we cannot have both of them competing for the same operand (--a++), so when evaluating an expression and calculating operands values it's like they are of the same priority. I was wondering if anyone can give me an example when this might not be the case, because I can't construct any. Looks like that tables about operators precedence just make confusion in this case.

(p.s. I am clear about other unary operators, only these two confuses me, or their "relationship" regarding priority)
 
Stephan van Hulst
Saloon Keeper
Posts: 14798
333
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You won't be able to make an example with a pre-increment or pre-decrement operator. The rule is there to accomodate the unary plus operator (+), the unary minus operator (-) and the bitwise ones' complement operator (~).

The higher precedence of postfix operators ensures that you can write -x++ and it will compile. If the postfix operators had a lower precedence, you would have to write -(x++).
 
Stephan van Hulst
Saloon Keeper
Posts: 14798
333
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ivana Kilibarda wrote:Looks like that tables about operators precedence just make confusion in this case.


They're technically correct though. When the compiler encounters ++x++, it will interpret it as ++(x++), and then it will tell you that the pre-increment operator expects a variable. If the pre-increment operator had a higher precedence, the compiler would spit out an error saying that the post-increment operator expects a variable.
 
Stephan van Hulst
Saloon Keeper
Posts: 14798
333
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As a final point, hopefully to satisfy your question: the precedence rules for pre-increment and pre-decrement operators are there as a logical consequence of how the compiler is built, the compiler wasn't necessarily built in a way to explicitly include precedence rules for these two operators.
 
Ivana Kilibarda
Greenhorn
Posts: 29
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I wasn't arguing that table is correct

This clarifies it though

Stephan van Hulst wrote:the precedence rules for pre-increment and pre-decrement operators are there as a logical consequence of how the compiler is built



Thank you for your answer, I understand now why
 
Ranch Hand
Posts: 574
VI Editor Chrome Linux
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
IMHO, things like "y = ++x + x++" should never be done.  I come from a C background, where it was up to the compiler to determine if ++x or x++ got evaluated first.  Java may be different, I don't need to know the grisly details of evaluation order because I don't do stuff like this.


 
Marshal
Posts: 77577
372
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jim Venolia wrote:IMHO, things like "y = ++x + x++" should never be done.

Agree. I have see things even worse.

I come from a C background, . . . . Java may be different . . .

Java® is different. At least...is well‑defined in Java® (i ends up as 3). I once tried that on three C compilers and two produced 3; the third gave 4 as the result
 
Jim Venolia
Ranch Hand
Posts: 574
VI Editor Chrome Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In both C and Java i should be 3.  You assign it before you increment it.

That said, if someone who reported to me wrote that line they would know I strongly disapproved.  Quite possibly whilst living in a dishwasher box under an overpass.
 
Campbell Ritchie
Marshal
Posts: 77577
372
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jim Venolia wrote:In both C and Java i should be 3.  You assign it before you increment it.

That behiour is required by the Java® Language Specification, but the behaviour in C isn't strictly deined, or at least it wasn't when I got that code to produe 4. The rules in C may have changed; I don't know.

That said, if someone who reported to me wrote that line they would know I strongly disapproved.  Quite possibly whilst living in a dishwasher box under an overpass.

No, they have to move into the cardboard box after writing that sort of code
 
Farmers know to never drive a tractor near a honey locust tree. But a tiny ad is okay:
The Low Tech Laboratory Movie Kickstarter is LIVE NOW!
https://www.kickstarter.com/projects/paulwheaton/low-tech
reply
    Bookmark Topic Watch Topic
  • New Topic