• 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
  • Liutauras Vilda
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Junilu Lacar
  • Tim Cooke
Saloon Keepers:
  • Carey Brown
  • Stephan van Hulst
  • Tim Holloway
  • Peter Rooke
  • Himai Minh
Bartenders:
  • Piet Souris
  • Mikalai Zaikin

Simple precedence question.

 
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The way I understand it && has a greater precedence than ||.
So what would the output be here?

 
Jim Crawford
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'll probably be kicked to the biginner corner again for this easy question, but I don't see why the above doesn't print:
B
C
 
Author & Gold Digger
Posts: 7617
6
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
No I won't kick you to the beginner forum since this question is interesting on the SCJP point of view.
Let's dig into it.
Actually the code example you give boils down to the following expression:
A || B && C
(whether A, B and C are boolean primitive variables, boolean literals or boolean-returning methods is not important.)
Java evaluates expression from the left to the right respecting the precedence order. In this case, when the runtime starts evaluating this expression it sees that it has to deal with a || (short-circuit OR) operation. It also sees that the first operand is A and the second is, well, it doesn't need to know that until A has been evaluated. When starting the evaluation of the expression what the runtime sees is
A || ??
If the runtime finds out that A evaluates to false, then it will investigate further and evaluate the second operand which is B && C. But in this case, the runtime figures out that B is true and that there is thus no need to go further. That's why only A gets printed out.
[ February 07, 2003: Message edited by: Valentin Crettaz ]
 
Jim Crawford
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I suspected something along these lines, but I fail to see the role that precedence plays then...
I can understand that this is possible as an optimization, but isn't it true that the || should be ignored until the && is complete?
I could be missing the point (and didn't have much sleep last night)
 
Valentin Crettaz
Author & Gold Digger
Posts: 7617
6
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Could you please take a look at the following document and tell me if it is of any help:
http://www.atkinson.yorku.ca/~sychen/ITEC1620/Tutorial3.pdf
Java performs what we call automatic binding, that is, the following expression
A && B || C && D
will be evaluated as
(A && B) || (C && D)
and not as
A && (B || (C && D))
or as
A && (B || C) && D
In our case, A || B && C will be evaluated as
A || (B && C) but since || is a short circuit the second operand never gets evaluated if A is true.
[ February 07, 2003: Message edited by: Valentin Crettaz ]
 
Jim Crawford
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I found a possible answer in this thread.
I guessed I missed it in the JLS etc. No doubt that it could be hidden there somewhere. Will look at the PDF now as well. Thanks.


1. in the 1st if statement. the order of evaluation review the left poriton of the
short circuit OR first. then, the short circuit OR is evaluated. followed by
any statements after the short circuit OR. the point being. for both && and | |,
the statement to the left are evaluated before operator precedence is applied.

since the left operator is TRUE. the operator to the right of | | is never evaluated. the operator to the right of && will always be evaluated.
2. ie.
b is three
b is less than 4
therefore the first statment is TRUE
2+3 is 5
5 is greater than 0
therefore the second statemend is TURH
the answer is TRUE
Hope this clears things up.
Monty
<hr></blockquote>
[ February 07, 2003: Message edited by: Jim Crawford ]
 
Jim Crawford
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A long discussion on Google groups
 
Jim Crawford
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think this is the story (although there was a part about grammer that looked interesting as well)


From: Eric Blake (e_blake@email.com)
Subject: Re: Operator Precedence
View: Complete Thread (20 articles)
Original Format
Newsgroups: comp.lang.java.programmer
Date: 2001-04-13 19:21:30 PST
"Scott D. Isaac" wrote:
> ..
> 12. Short-circuit: &&
> 13. Short-circuit: || ..
>
> However, I have found the JLS (section 15) to be vague about precedence.
> While this is the order in which they are presented, there is no mention
> that that is the order of precedence.
It is explicitly stated within the grammar of chapter 15, but is lacking
in the grammar of chapter 18, as well as the descriptive text of chapter
15. Hopefully the 3rd edition JLS will rectify this and make the
chapter 18 grammar express precedence, as well as describe it better in
the description.
>
> So, what's my beef you ask?
>
> Through experimentation, I have found that 12 and 13 are at the same level
> of precedence. This contradicts what I have seen written and the JLS is
> silent on this matter.
The difference in precedence is observable when the first term evaluates
as true.
With (a||b)&&c, c must be evaluated if a is true. However, with
a||(b&&c), the entire (b&&c) term is never evaluated, because ||
short-circuits.
So, if || and && have equal precedence, a||b&&c is equivalent to
(a||b)&&c, since they group left-to-right; you would get a side-effect
from evaluating c in 6 of the 8 input cases, and a true result in only 3
of the 8.
However, since && has a higher precedence, a||b&&c is equivalent to
a||(b&&c), and you only get a sige-effect from c in 2 of the 8 input
cases, and a true result in 5 of the 8.
Here's a program to print out all the cases.

This program outputs (with some post-formatting applied):
false false false a b false a b false a b false
false false true a b false a b false a b false
false true false a b c false a b c false a b c false
false true true a b c true a b c true a b c true
true false false a true a c false a true
true false true a true a c true a true
true true false a true a c false a true
true true true a true a c true a true
--
Eric Blake


[ February 07, 2003: Message edited by: Jim Crawford ]
 
Jim Crawford
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Summary:
You can express precedence with brackets:
thus
a || b && c
becomes
a || (b && c)
which is easy to understand.
The || still gets executed first and the brackets illustrate what is done according to precedence.
Just like Valentin said, but I didn't make the connotation immediately.
Cheers.
 
Valentin Crettaz
Author & Gold Digger
Posts: 7617
6
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Happy you got it
 
Ranch Hand
Posts: 234
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks,
I struggled with the same problem, but now I finally got it.
Bart
 
Ranch Hand
Posts: 2120
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I agree we could say && has a greater precedence than ||. But we must be aware of the code that the compiler generates. Because if someone thinks that a||b&&c will be treated as a||(b&&c) there is a problem: even though both will yield the same result, if the evaluation of b and c has side effects, they will not happen.
The point is that || and && will not short-circuit the same part of the remaining expression.
If the expression consist of a serie of && a || operators with no interwined parentheses the output of javap shows the following two points:
a) A true value before || will short-circuit the whole of the remaining expression. Thus no remaining side effects will occur. It is funny to say that remaining && operators have a greater precedence because their operands are not evaluated at all.
b) A false value before && will short-circuit only up to the left operand of the first || to its right. Thus side effects are possible starting from the right operand of the cited ||.
I guess this difference in the implementations of the two operators allows for the "strange" bigger precedence of && over ||.
Here goes the code produced by the compiler for two examples:

Note that the real values of the variables will not matter to the code generated by the compiler; at least in this case.
Waiting for comments
 
reply
    Bookmark Topic Watch Topic
  • New Topic