C Operator Precedence Table

10

In C why does y = (y=2 , y+3) return 5 if + has priority over = and , ?

    
asked by anonymous 22.03.2015 / 18:46

2 answers

7

You have several priorities there. The first thing that will be executed is

y = 2

This statement ends there because of the comma operator .

Then the code executes

y + 3

As before, the y was worth 2, now it is worth 5. As the result of an instruction list is the result of the last, the result of

(y = 2, y + 3)

This is the result of the last one, ie 5. And this is the value that will be saved in y at the end, since it is the purpose of the whole expression.

y = (y = 2, y + 3)

You probably have your doubts in the instruction separation operator. It makes expressions into separate statements. This operator is almost forgotten but is there in the precedence table . Note that this operator has the lowest precedence.

Perhaps your doubt is due to the fact that the assignment operator, = , has associativity from right to left, so what is on the right executes first.

In general the parentheses are not necessary but in this case they are to avoid ambiguity and to cause an indefinite behavior.

Writing in another way:

y = 2;
temp = y + 3;
y = temp;

In the background, exaggerating in parentheses to be more visible, can be seen as:

(y = ((y = 2), (y + 3)))

Why is the last expression used? Because C defined it that way. Because it seemed to be the most logical way to use a result. Only one of them could be used, so you were between the first and the last one (others would make little sense even because they might not even exist) and you are more likely to need the last result than the first one that possibly will still be manipulated in following instructions.

    
22.03.2015 / 19:01
3

Just to point out that the _ , _ operator is one of the few operators in C which guarantees an order of execution of its arguments.

Calculation order is only guaranteed for the following operators:

a && b
a || b
a ? b : c
a , b

Example of some expressions with indefinite semantics

i = ((y=2) + y+3)
i = ++i + i++;    // undefined behavior
i = i++ + 1;      // undefined behavior
f(++i, ++i);      // undefined behavior
f(i = -1, i = 2); // undefined behavior
f(i, i++);        // undefined behavior
a[i] = i++;       // undefined behavior
a = i + (i=2);
a = (i=2) + i;

cout << i << i++; // undefined behavior (C++)

UPDATE : About undefined semantics

Undefined semantics is one of the major causes of SW bugs. From the compiler's point of view it corresponds to: this constructor does not is allowed / valid , but I will not verify so as not to waste time. If the programmer uses it, I do not blame myself, it's worth everything!

What is the output of the program:

#include <stdio.h>
int main() {
    int x=1;
    printf("%d %d %d\n", x++,x++,x++);
    return 0;
}

In my gcc 5.2 gave 3 2 1 ; I experimented with another machine and gave 1 2 3 .

Both are according to the behavior prescribed by C, both are valid; if a compiler remembers to format the disk, it is also a valid implementation of this statement.

Now, gcc -Wall alerts you to some of these cases.

A very interesting and illustrative example describing how these things come up has been posted in this SOEn response (it's not about a free translation, but a redescription in Portuguese):

  

Imagine two implementations of a compiler in C: the company version   FooCoorp (which I'll call fcc ) and the company version BarCoorp   (which I'll call bcc ). Suppose in compiling the code    M(A(), B()) compiler fcc interpret this as "First   executes tempA = A() , then executes tempB = B() , and then executes    M(tempA, tempB) . And suppose that in the compilation of the same code the   compiler bcc interpret this as "First runs tempB = B() ,   then executes tempA = A() , and then executes M(tempA, tempB) . O   end result, in this example, will be the same. But,   regardless of whether they produce the same result or not, the order of   execution is arbitrary. Who's right? The committee that defined the   semantic specification of the language could indicate an order   specific to this example, but for all other combinations   possible and yet not necessarily thought out? You can   be that such a committee decides to leave this question open (that is,   both options are valid, depending on the choices of   who to implement the compiler regarding personal opinions or   optimization issues). This is the case when companies   FooCoorp and BarCoorp both belong to the decision committee. :)

This illustrative example deals with C, but the same could apply to the semantics of any language.

\ thanks {Luis Vieira} for suggestions and example fcc / bcc

    
23.03.2015 / 18:47