| Author |
Operator Precedence involving && and ||
|
Arnold Kesselaar
Greenhorn
Joined: Feb 28, 2003
Posts: 14
|
|
Firstly I would like to say that JavaRanch is REALLY GREAT! I'va learned so much from you guys (and ladies). Anyway, I ran across this question in a mock exam: class A { static boolean a; static boolean b; static boolean c; public static void main (String[] args) { boolean x = (a = true) || (b = true) && (c = true); System.out.print(a + "," + b + "," + c); } } What is the result of attempting to compile and run the above program? The answer is : Prints: true,false,false The right operand of the conditional "or" operator is not evaluated if the left hand operand is true. In this case the right hand operand of the conditional "or" operator is the result of the conditional "and" expression. Therefore, the conditional "and" expression is not evaluated. My question is why doesn't the && operator get evaluated first since it has a higher prioty? Thanx. [Dan changed the title to something more descriptive. Please try to use descriptive titles!] [ February 28, 2003: Message edited by: Dan Chisholm ]
|
 |
Dan Chisholm
Ranch Hand
Joined: Jul 02, 2002
Posts: 1865
|
|
Please see the following thread. http://www.coderanch.com/t/240688/java-programmer-SCJP/certification
|
Dan Chisholm<br />SCJP 1.4<br /> <br /><a href="http://www.danchisholm.net/" target="_blank" rel="nofollow">Try my mock exam.</a>
|
 |
Jose Botella
Ranch Hand
Joined: Jul 03, 2001
Posts: 2120
|
|
Welcome to the Ranch arnold. I am quoting from myself
In the absense of parentheses and &&, || operators when considering if the operation of a given operator is performed or not, we must note the precedence of the operators to its left and the precedence of those to its right. An operation is performed before the operators to its left if they have fewer precedence and before the operators to its right if the precedence of those is equal or fewer.
Applying it to the example: = has fewer precedence than ||, thus || should be considered against the following operator. && has a bigger precedence than ||, as a consequence, the precedence of && should be considered against the precedence of the following operator; but it is not because parentheses and &&, || affect this proccess (*). In fact, the evaluation of true at the left side of || will short-circuit the rest of the expression. I have seen a proof of the higher precedence of && against || in a linked posted by Val. Try a brute attack. Provide the program with all the possible boolean values for the expression and write down the results. Now make the calculations for the cases where && has a higher precedence, and the other way round. Compare the result of the execution with both to see that the program behaves as if && had a higher precedence. Thus I would say && has a higher precedence than ||. (*) operands are evaluted from left to right in this chain of comparations between adjacents operators [ April 14, 2003: Message edited by: Jose Botella ]
|
SCJP2. Please Indent your code using UBB Code
|
 |
Arnold Kesselaar
Greenhorn
Joined: Feb 28, 2003
Posts: 14
|
|
Thank you for the warm welcome. I think I get it now. The following java stack analysis really made it clear to me. Is this correct? Jose Francisco Colom L�pez greenhorn Member # 43952 posted January 28, 2003 01:48 AM -------------------------------------------------------------------------------- I think the different operands in a expressi�n are always evaluated in the order their appear in the expression. Other point is when the operation is performed: that depends on operator precedence. Example 1: a + b * c a evaluated b evaluated c evaluated * performed (with c and b) + performed (with the former result and a) Example 2: a * b + c a evaluated b evaluated * performed (with a and b) c evaluated + performed (with the former result and c) Example 3: a || b && c a evaluated: if false doesn't eval. the right expr
|
 |
Sarma Lolla
Ranch Hand
Joined: Oct 21, 2002
Posts: 203
|
|
[ February 28, 2003: Message edited by: Sarma Lolla ]
|
 |
Sarma Lolla
Ranch Hand
Joined: Oct 21, 2002
Posts: 203
|
|
Example 3 is also wrong. When the following code is executed you get the output as 0 1 2 true
|
 |
Jose Botella
Ranch Hand
Joined: Jul 03, 2001
Posts: 2120
|
|
Arnold I think you are right except that obviously the value that short-circuit a || operator is true, not false. ___________________________________________________ Sarma, to see the exact sequence in which the "interpreter" will execute an arithmethic/logical expression I have used "javap -c Test" --once Test.java is compiled--. The bytecodes for the main method are:
Method void main( java.lang.String[]) 0 bipush 10 2 istore_1 3 iconst_0 4 invokestatic #2 Method boolean m(int) 7 ifne 24 10 iconst_1 11 invokestatic #2 Method boolean m(int) 14 ifeq 28 17 iconst_2 18 invokestatic #2 Method boolean m(int) 21 ifeq 28 24 iconst_1 25 goto 29 28 iconst_0 29 istore_3 30 getstatic #3 Field java.io.PrintStream out 33 iload_3 34 invokevirtual #4 Method void println(boolean) 37 return
In line 3 the argument to m(int) is pushed into the operand stack. In line 4 m(int) is invoked with argument in the oparand stack. Line 7 jumps to the assignation of 1 to b in the case that the left operand of || is true. In this way the short-circuit of || is implemented In line 10 we continue evaluating the right operand of ||, but only because its left operand is false. In line 14 the short-circuit of && operator is performed: if its right operand happens to be false it jumps to the assignation of false to b. In this way the rest of the expression is not performed. ___________________________________________ I think that with these kind of observations my previous post can be verified. I would say that a || operator short-circuits the whole of the remaining expression, providing no parentheses come into action. The point is that the && operator does not behave exactly equal. A false value to the left of && will short-circuit only sucessive && operators to its right, untill the first || operator on its right. For instance:
public class Test {static boolean a, b, c, d, e; Test(){ e = a && b && c || d; } }//the values of the variables won't matter to compiler: Method Test() 0 aload_0 1 invokespecial #1 Method java.lang.Object() 4 getstatic #2 Field boolean a 7 ifeq 22 10 getstatic #3 Field boolean b 13 ifeq 22 16 getstatic #4 Field boolean c 19 ifne 28 22 getstatic #5 Field boolean d 25 ifeq 32 28 iconst_1 29 goto 33 32 iconst_0 33 putstatic #6 Field boolean e 36 return
Note that if a is false the jump is to the evaluation of d. It does not short-circuit the whole expression as || would do.
|
 |
Sarma Lolla
Ranch Hand
Joined: Oct 21, 2002
Posts: 203
|
|
Jose, Thanks for correcting me. I am under the impression that all the operators are evaluated at least before taking the short circuits. But I am wrong.
|
 |
Sarma Lolla
Ranch Hand
Joined: Oct 21, 2002
Posts: 203
|
|
I still believe this example mentioned above is wrong. Example 2: a * b + c a evaluated b evaluated * performed (with a and b) c evaluated + performed (with the former result and c) Can any one correct me if I am wrong?
|
 |
Jose Botella
Ranch Hand
Joined: Jul 03, 2001
Posts: 2120
|
|
The compiler will correct you as it did many times with me.
public class Test {static int a, b, c, d; {d = a * b + c; } } Method Test() 0 aload_0 1 invokespecial #1 Method java.lang.Object() 4 getstatic #2 Field int a 7 getstatic #3 Field int b 10 imul 11 getstatic #4 Field int c 14 iadd 15 putstatic #5 Field int d 18 return
imul multiplies the two operands in the top of the operand stack before c is pushed into it.
|
 |
 |
|
|
subject: Operator Precedence involving && and ||
|
|
|