-2
main(){
    int a = 5;
    int b = 6;
    printf("%d %d %d",a==b,a=b,a<b);
}

Output in my testing

1 6 1

In above program I am expecting output as 0 6 0 . In some compilers it is giving this output (e.g. Xcode) but where as in some other compilers it is giving output as 1 6 1 . I couldn't find the explanation . It is also the case of Sequence point.

Consider this below program

main(){
    int a = 5;
    int b = 6;
    printf("%d %d %d",a<b,a>b,a=b);
    printf("%d %d",a<=b,a!=b);
}

Output in my testing

0 0 6 1 0

this below program is giving the correct output which i am expecting which is 0 0 6 1 0 but why the above program is not giving the output as 060 in most of the compilers

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • "It is also the case of Sequence point" not sure what you mean here. The `,` in this case is a function parameter list, which does not come with a sequence point. Not to be confused with the (obscure) comma operator which does come with a sequence point. Relevant sequence points in this code are: one at the semi colon of `b=6`, one after all the parameters have been evaluated but before the printf function is called, and one after the function is done. – Lundin Jun 25 '15 at 09:59

3 Answers3

6

C standard says:

C11: 6.5 (p2):

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined [...]

This means your program invokes undefined behavior. In the statements

printf("%d %d %d",a==b,a=b,a<b);  

and

printf("%d %d %d",a<b,a>b,a=b);

the side effect to a is unsequenced because standard says:

haccks
  • 104,019
  • 25
  • 176
  • 264
2

= is the assignment operator, which changes the value of the left operand.

FWIW, the comparison operator is ==

In this statement

 printf("%d %d %d",a==b,a=b,a<b);

you're changing the value of a (a = b) and trying to read the value (other two cases) to perform other operations, workout having a sequence point in between. Also, the order of evaluation of the function arguments are not defined (or unspecified) by the standard.

To quote the C11 standard, chapter §6.5, (emphasis mine)

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.

So, the above statement produces undefined behaviour.


Note: The recommended signature of main() is int main(void).

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

in above program i am expecting output as 0 6 0

You are expecting argument evaluation from left to right (reading direction of english). But the order of evaluation may go from left to right, right to left or in some other order. A program should not depend on the order of evaluation of function arguments.

printf("%d %d %d",a==b,a=b,a<b);
// 1. Evaluate the following in no specific order
//       (a==b), (a=b) and side effects, (a<b)
//       (Warning: Depending on the order, result may be different)
// 2. Pass "%d %d %d" as first argument, the result of
//       (a==b) as second argument, result of of (a=b) as
//       third argument and result of (a<b) as fourth
//       argument of printf

In C order of argument evaluation is unspecified. So it can evaluate the arguments in any order. As you are changing the value of variable a (using assignation operator =) in one of the argument, use the following for more consistent result.

printf("%d ",a==b); // Evaluate (a==b) and pass as second argument of printf
printf("%d ",a=b);  // Evaluate (a=b) and side effects and pass as second argument of printf
printf("%d" ,a<b);  // Evaluate (a==b) and pass as second argument of printf

Without this your program invokes undefined behavior because you are updating and reading the value of a before the sequence point. But in latter case there is no ambiguity and thus program shows a well defined behavior.


p.s. Don't confuse between comma used in function parameter list and the comma operator

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
  • 1
    Footnote is very useful. This is comma _as_ separator, not _comma operator_, right? – Sourav Ghosh Jun 25 '15 at 09:59
  • int the below program also there is a=b statement but it is giving correct output in all the different machines why ? – Himanshu Kaushik Jun 25 '15 at 10:07
  • @HimanshuKaushik The program does not suffer undefined or unspecified behavior. You are doing assignation only in the second line and arguement is the result of expression `a = b` which is same as `a`. – Mohit Jain Jun 25 '15 at 10:33
  • @HimanshuKaushik There are just 2 sequence points in former code: One after all 3 arguments are evaluated and one after call to `printf` is executed. On the other hand, in latter code, there are 2 sequence point per line or per `printf`. Once after argument evaluation and once at semicolon. – Mohit Jain Jun 25 '15 at 10:37