Evaluation of if's

daniel at sdl.mdcbbs.com daniel at sdl.mdcbbs.com
Mon Jun 17 01:04:41 AEST 1991


Sorry about the previous posting, got news_edit logical wrong.

In article <1991Jun13.184843.508 at ulkyvx.bitnet>, pgheit01 at ulkyvx.bitnet writes:

> 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


A quick perusal of my ANSI C spec indicates this is not correct.
Section 3.3  reads :-

    "Except as indicated by the syntax or otherwise specified later (for the
function call (), &&, ||, ?:, and comma operators), the order of evaluation
of subexpressions and the order in which side effects take place are both 
unspecified."

So you are correct about && but not about ==.

Section 3.3 also reads

    "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 prior value shall be accessed only to determine the value
to be stored. (ftnote 25)"

"(ftnote 25)
This paragraph renders undefined statement expressions such as
    i = ++i + 1;
whilst allowing
    i = i + 1;
"                

On assigment operators the ansi standard states that 

   "An assigment expression has the value of the left operand after the 
assignment, but is not an lvalue""..."The side effect of updating the stored
 value of the left  operand shall occur between the previous and the next 
sequence point."

Now my copy of the standard is only a draft, so it may have been updated to
cover this rather nasty case. But my guess is that it hasn't. Anyway where 
does this leave us? My guess is that the value of the the expression in 
question is completely undefined (as is thevalue stored in i). A straw poll 
of the 'ANSI' C compilers in house yields the following results for the 
given code.

#include <stdio.h>

main(int argc,char **argv)
  {
    int i = 0;

    if ((i = 1) == (i = 2))
      {
        printf("Branch 1, i = %d\n",i);
      }
    else
      {
        printf("Branch 2, i = %d\n",i);
      }
  }

Sun :-
Branch 1, i = 2

Vax :-
Branch 1, i = 2  

Apollo :-
Branch 1, i = 2


However K&R variants produce different results

Sun :-
Branch 2, i = 1

Dec Risc:-
Branch 1, i = 2


Read these results as you will, to me it merely confirms that exepressions
with side effects should be avoided at all costs. Indeed we have developed 
an in House C variant which produces errors for these sorts of problems.

This case is an interesting example of hard to is to provide a 'complete' 
specification for a piece of code. After all an ANSI C compiler isn't
one of the largest pieces of software around. And, if we can't get the
specification for something as well defined (obviously not that well
defined as a compiler correct, where does that leave us with respect 
to some of the larger more complex software projects around 
(air traffic control, fly by wire ......)?

                                                              
Daniel Dignam                           Shape Data Limited (McDonnell Douglas)
 Internet: daniel at sdl.mdcbbs.com           46 Regent Street
     UUCP: ...!uunet!sdl.mdcbbs.com!daniel   Cambridge CB2 1DB
    Voice: +44 223 316673  Fax: +44 223 316931  United Kingdom



More information about the Comp.lang.c mailing list