C & C++ DISCUSSION

Why is i = i++ + ++i undefined behaviour in C, and why do compilers disagree on the result?

Started by teferitirfe undefined behavioursequence pointsorder of evaluationincrement operatorscompiler warnings
4 replies 248 views 5 participants
Latest activity · 30 Sep 2026

Why is i = i++ + ++i undefined behaviour in C, and why do compilers disagree on the result?

teferitirfe C & C++ Forum
#1

A quiz from class has int i = 3; i = i++ + ++i; and asks for the final value of i. Two compilers give me two different values, and with warnings enabled GCC says the operation on i may be undefined. A similar line, printf("%d %d\n", i++, i++);, also prints different numbers on different machines.

I expected the operators to be applied left to right according to precedence. Why is there no single correct answer, and how do I know which expressions are safe?

Community replies 4

Re: Why is i = i++ + ++i undefined behaviour in C, and why do compilers disagree on the result?

#2

Precedence and associativity only decide how an expression is grouped, that is, which operands belong to which operator. They say nothing about when the side effects, the stores into i, take place. C fixes that order only at sequence points: the end of a full expression, after the first operand of &&, ||, ?: and the comma operator, and after the arguments of a function call have been evaluated.

The rule is that between two sequence points an object may be modified at most once, and its previous value may be read only to work out the value to store. i = i++ + ++i modifies i three times with no sequence point in between, so the standard places no requirement on the result at all.

Re: Why is i = i++ + ++i undefined behaviour in C, and why do compilers disagree on the result?

#3

It helps to separate three terms. Unspecified means the compiler chooses from a set of allowed behaviours and need not say which, for example the order in which function arguments are evaluated. Implementation-defined means it chooses and documents the choice, such as the result of right-shifting a negative int. Undefined means no requirements: any value, a different value at another optimisation level, or code that the optimiser removes.

So f(a(), b()) only has an unspecified call order and is fine when the two calls are independent. printf("%d %d\n", i++, i++) is undefined, because the commas between arguments are not comma operators and the two modifications of i are unsequenced.

Re: Why is i = i++ + ++i undefined behaviour in C, and why do compilers disagree on the result?

#4

A workable rule: never modify a variable twice in one statement, and do not read it elsewhere in a statement that modifies it. a[i] = i++;, i = i++; and x = buf[n++] * buf[n++]; are all the same trap.

A close relative shows up in embedded code when assembling a word from a stream: v = (read_byte() << 8) | read_byte();. This is not undefined, but the order of the two calls is unspecified, so another compiler or optimisation level can swap the bytes. Use separate statements: hi = read_byte(); lo = read_byte(); v = (hi << 8) | lo;.

Re: Why is i = i++ + ++i undefined behaviour in C, and why do compilers disagree on the result?

#5

Let the compiler find these. GCC reports them under -Wsequence-point and Clang under -Wunsequenced; both are active when you build with -Wall, so treat that warning as an error. For undefined behaviour that only appears at run time, such as signed overflow or an oversized shift, run the code on a PC built with -fsanitize=undefined.

One note if you also write C++: C++17 sequenced the right-hand side of an assignment before the left, so i = i++; became well defined there and leaves i unchanged. C did not adopt that, and the quiz expression stays undefined in both languages because the two operands of + are still unsequenced. The correct quiz answer is "undefined behaviour", not a number.

TEP COMMUNITY