Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C side effects in gcc (prefix/postfix operator and precedence) [duplicate]

Tags:

c

gcc

i have small C code:

#include<stdio.h>
int main() 
{
    int  z[]= {1,2,3,4,5,6};
    int i = 2, j;
    printf("i=%d  \n",i); 

    z[i] = i++;

    for (j=0;j < 6;j++ )
       printf ("%d ", z[j]);

    printf("\ni=%d \n",i); 
}

output:

i=2  
1 2 2 4 5 6 
i=3

The order of precedence to evaluate the expression is First, z[i] is evaluated. As i is 2 here, it becomes z[2]. Next, i++ is evaluated i.e 2 is yielded and i becomes 3. Finally, = is executed, and 2 (i.e value yielded from i++) is put to z[2]

This explains the above output i.e 1 2 2 4 5 6

But if we change the above code from i++ to ++i i.e

#include<stdio.h>
int main() 
{
    int  z[]= {1,2,3,4,5,6};
    int i = 2, j;
    printf("i=%d  \n",i); 

    z[i] = ++i;

    for (j=0;j < 6;j++ )
       printf ("%d ", z[j]);

    printf("\ni=%d \n",i); 
}

Then the Output is strangely different, which is:

i=2  
1 2 3 3 5 6 
i=3

if we go by the above precedence (what C spec says [index] are bound earlier than ++) then the output should have been 1 2 3 4 5 6.

I just wish to know that why the above order of precedence does not explains this ?

my compiler is gcc 4.5.2 on ubuntu 11.04

Thanks and Regards, Kapil

like image 286
Kapil Avatar asked Dec 26 '22 03:12

Kapil


1 Answers

z[i] = ++i; results in undefined behavior:

6.5 Expressions
...
2 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.84)
84) This paragraph renders undefined statement expressions such as

    i = ++i + 1;
    a[i++] = i;
while allowing

    i = i + 1;
    a[i] = i;

Note that precedence only controls the grouping of operators and operands; it does not control the order of evaluation.

The side effect of the ++ operator in ++i is unsequenced relative to the [] operator in z[i]; the compiler is not required to evaluate the two expressions in any particular order. Also note that the side effect of ++i need not be applied immediately after the expression is evaluated; it only needs to be applied before the next sequence point.

like image 194
John Bode Avatar answered Mar 09 '23 01:03

John Bode