Reputation: 287
I am working with the C operator precedence table to better understand the operator precedence of C. I am having a problem understanding the results of the following code:
int a, b;
a = 1;
b = a++; // does not seem to follow C operator precedence
Using the precedence table of C operators, I can not explain why with the postfix ++
operator, first the assignment is evaluated and then the increment.
The postfix increment operator (++
) has the highest precedence in C and the assignment operator (=
) has the lowest precedence. So in the above code first postfix ++
must executed and then assignment =
. Therefore both variables a
and b
should equal 2 but they don't.
Why does the C operator precedence seems not to work with this code?
When doesn't the highest precedence of postfix ++
show itself?
Upvotes: 5
Views: 1565
Reputation: 123468
Precedence only determines which operators are grouped with which operands during parsing. It does not control order of evaluation. ++
having a higher precedence than =
only means that b = a++
is parsed as b = (a++)
rather than (b = a)++
.
The ++
operator (both unary and postfix forms) has a result and a side effect. In the expression b = a++
, the result of a++
is the current value of a
- that's what gets assigned to b
. The side effect of a++
is to add 1 to a
.
The order in which the assignment to b
and the update to a
occur is unspecified. The most straightforward is
b <- a
a <- a + 1
but the following is also allowed:
tmp <- a
a <- a + 1
b <- tmp
The result of ++a
is the current value of a
plus 1, and the side effect is to add 1 to a
. Do not assume that in an expression like b = ++a
that a
is updated before b
. Again, the order of evaluation could be something like
b <- a + 1
a <- a + 1
The actual evaluation order depends on your compiler, optimization settings, even the surrounding code.
The only operators that force left-to-right evaluation of expressions are the &&
, ||
, ?:
, and comma operators.
Upvotes: 5
Reputation: 140188
The precedence happens during the parsing. It means that ++
applies to a
, not to b = a
.
But ++
means post incrementation, so performed after a
is evaluated to be assigned to b
If you want both to take the value 2
perform a pre-incrementation:
b = ++a;
Upvotes: 3
Reputation: 223972
This had nothing to do with precedence. It's a matter of how the postfix ++
operator works.
The postfix ++
operator evaluates to the current value of its operand, and has the side effect of incrementing its operand. In contrast the prefix ++
operator evaluates to the incremented value of its operand.
int a, b;
a = 1;
b = a++; // b is 1, a is 2
b = ++a; // b is 3, a is 3
This behavior of the postfix ++
operator is documented in section 6.5.2.4p2 of the C standard:
The result of the postfix
++
operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it). See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. The value computation of the result is sequenced before the side effect of updating the stored value of the operand. With respect to an indeterminately-sequenced function call, the operation of postfix++
is a single evaluation. Postfix++
on an object with atomic type is a read-modify-write operation with memory_order_seq_cst memory order semantics.
And the prefix ++
operator is documented in section 6.5.3.1p2:
The value of the operand of the prefix
++
operator is incremented. The result is the new value of the operand after incrementation. The expression++E
is equivalent to(E+=1)
. See the discussions of additive operators and compound assignment for information on constraints, types, side effects, and conversions and the effects of operations on pointers.
Upvotes: 5