Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!think.com!spool.mu.edu!olivea!oliveb!veritas!amdcad!dvorak.amd.com!proton!tim From: tim@proton.amd.com (Tim Olson) Newsgroups: comp.lang.c Subject: Re: Evaluation of if's Message-ID: <1991Jun14.164218.26713@dvorak.amd.com> Date: 14 Jun 91 16:42:18 GMT Article-I.D.: dvorak.1991Jun14.164218.26713 References: <1991Jun7.232119.17834@cs.ucla.edu> <1991Jun13.184843.508@ulkyvx.bitnet> Sender: usenet@dvorak.amd.com (Usenet News) Reply-To: tim@amd.com (Tim Olson) Distribution: usa Organization: Advanced Micro Devices, Austin, TX Lines: 74 In article <1991Jun13.184843.508@ulkyvx.bitnet> pgheit01@ulkyvx.bitnet writes: | AAAAAARRRRRGGGGHHHHH! | | The statement if ((i = 1) == (i = 2)) is valid. ANSI C evaluates conditions | from left to right. *ALWAYS* ANSI C short-circuits a conditional statement | *ALWAYS* (unless you tell it not to) That makes possible the type of statment | if ((x != 0) && (1/x < 9)) | STATMENT; | (note that the inner sets of parentheses are not needed, and "< 9" could be | changed to whatever you need to test. Also "x != 0" can just be "x".) | | ANSI guarratees that the second statement will not be executed(and division by | zero will not result) because the statment is false after the first condition | if x == 0. There are a number of fallacies in the statement above. The expression ((i=1) == (i=2)) is not valid, because the ANSI spec specifies that (3.3 EXPRESSIONS): "Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression." Furthermore, the spec states that (3.3 EXPRESSIONS): "Except [for operators] (), &&, ||, ?:, and "comma", the order of evaluation of subexpressions and the order in which side effects take place are both unspecified." The == operator is not a short-circuit operator, and the order of evaluation of its operands is undefined. | I did compile and run the code in question. The assignments do take place. | i takes on the value 1 after the first condition is "tested", and i takes on | the value 2 after the second condition is tested. After the if-statement is | executed, i is and will irrepairably be 2. That is not a proof, it is just an example. Here is a counterexample: ;1 |int i; ;2 | ;3 |f() ;4 |{ ;5 | return ((i=1) == (i=2)); const gr97,_i const gr96,2 ; (0x2) consth gr97,_i store 0,0,gr96,gr97 ;6 |} jmpi lr0 const gr96,1 ; (0x1) Yep -- the compiler generated code to store the value '2' into i, but returned a '1' as the value of the expression. This is valid code for the given expression. | My C teacher just loved to slip in questions like this one to see if anyone | knew the finer details of the precedence table. :-) This has nothing to do with precedence. -- -- Tim Olson Advanced Micro Devices (tim@amd.com) -- -- Tim Olson Advanced Micro Devices (tim@amd.com)