So what would the output be here?

B

C

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 ]

SCJP 5, SCJD, SCBCD, SCWCD, SCDJWS, IBM XML

[Blog] [Blogroll] [My Reviews] My Linked In

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)

Sheriff

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 ]

SCJP 5, SCJD, SCBCD, SCWCD, SCDJWS, IBM XML

[Blog] [Blogroll] [My Reviews] My Linked In

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.

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 ]

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 ]

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.

Sheriff

SCJP 5, SCJD, SCBCD, SCWCD, SCDJWS, IBM XML

[Blog] [Blogroll] [My Reviews] My Linked In

I struggled with the same problem, but now I finally got it.

Bart

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

SCJP2. Please Indent your code using UBB Code

It is sorta covered in the JavaRanch Style Guide. |