How to justify C postfix increment operator with precedence table?
Asked Answered
C

3

5

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?

Callie answered 6/2, 2019 at 20:24 Comment(3)
In case this isn't clear, precedence and associativity are independent from order of evaluation. It's understandable how these terms can be confused though.Eichler
a is retrieved for the assignment, then the memory location of a is incremented (not the retrieved value).Diamond
I think of the "post" in "postfix" as indicating that the increment occurs after everything else is evaluated. i.e char *str = "FreeBSD"; char increment() { ((*str++) + 1) }, the pointer is de-referenced, the arithmetic is applied, and the value returned (in this case a 'G'.) Only then is the increment applied. This was helpful when I began grappling with things like Duff's Device.Tellurium
P
3

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;
Paralyse answered 6/2, 2019 at 20:28 Comment(0)
C
5

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.

Calomel answered 6/2, 2019 at 20:27 Comment(0)
R
5

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.

Rrhagia answered 6/2, 2019 at 20:54 Comment(0)
P
3

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;
Paralyse answered 6/2, 2019 at 20:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.