2

I have a code which is small but I couldn't get why the output is like that.
Here it is

#include <stdio.h>

int f(int i, int j, int k);

int main(int argc, char const *argv[])  
{  
    int a;   
    printf("enter a\n");  
    scanf("%d",&a);  
    f(a,a++,a++);  
    printf("%d \n",a );  
    return 0;  
}  

int f(int i, int j, int k)  
{  
    printf("function arguments \n");  
    printf("%d %d %d\n",i,j,k );  
}   

input: 4
output:6 5 4

unwind
  • 391,730
  • 64
  • 469
  • 606
mani deepak
  • 401
  • 1
  • 4
  • 15
  • Compile your code with `gcc -Wall myprog.c -o myprog` and *gcc* will kindly tell you *warning: operation on ‘a’ may be undefined* – Déjà vu Feb 22 '13 at 15:30
  • 1
    @unwind: The accepted answer to the marked duplicate is not entirely correct. – Alok Save Feb 22 '13 at 15:41

2 Answers2

4

The accepted answer in the marked duplicate is Incorrect.


f(a,a++,a++); 

Causes Undefined behavior. It tries to modify the argument a without an intervening sequence point. Also, it is important to note that order of evaluation of function arguments is Unspecified. It can be:

  • Left to Right or
  • Right to Left or
  • Any magical order the compiler chooses.

If you are using GCC you can use the warning flag -wsequence-point to warn you of sequence point related undefined behaviors.


In GCC If you compile your program at strictest warning levels, the compiler will give you this diagnostic:

prog.c:10:18: error: operation on ‘a’ may be undefined [-Werror=sequence-point]
prog.c:10:18: error: operation on ‘a’ may be undefined [-Werror=sequence-point]


Reference:

C99 Standard §6.5.2.2:
Para 10:

The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.

Note that the quote only says that there is a sequence point before the actual function call, it does not imply there is a sequence point between evaluation of subexpression arguments.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • @pce: It is **Undefined behavior** and **not Unspecified behavior**. The proof is in the quotation you cited *C99 §6.5.2.2p10*, it states that there is a sequence point just before the function call it does not say there is a sequence point between the evaluation of subexpression arguments. – Alok Save Feb 22 '13 at 15:35
  • @pce What do you think of C11 §6.5p2? – autistic Feb 22 '13 at 15:45
  • @modifiablelvalue hehe, C11 is awesome. ^ – pce Feb 22 '13 at 16:11
  • 1
    @pce: I think its important here to note the difference between Unspecified and Undefined. Unspecified means you can expect the same observable behavior for a given implementation. Undefined behavior means you cannot rely on any observable behavior. It is latter and not former, so You cannot rely on this to be anything consistent on any implementation and OP needs to know that. – Alok Save Feb 22 '13 at 16:11
1

f(a,a++,a++); seems like undefined behaviour because:

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.

When you use undefined behaviour, there are no requirements from the C standard.

autistic
  • 1
  • 3
  • 35
  • 80
  • Thanx to all.I also saw many sources that we can't tell the specified sequence but there is a myth that parameter evaluation is from left to right while passing is from right to left.Is it true? – mani deepak Mar 03 '13 at 10:34