Does the definition int a = 0, b = a++, c = a++; have defined behavior in C?
Or almost equivalently, does the comma in an object definition introduce a sequence point as for the comma operator in expressions?
Similar questions have been asked for C++:
- Does `int a = 0, b = a` have undefined behavior?
- Is the comma in a variable list a sequence point?
- C++: variable declaration initialization order
The widely accepted answer for C++ is Yes, it is fully defined per paragraph 8/3 of the C++11 Standard:
Each init-declarator in a declaration is analyzed separately as if it was in a declaration by itself
Albeit this paragraph only refers to the syntax analysis phase and is not quite precise enough regarding the sequencing of operations at runtime.
What is the situation for the C language? Does the C Standard define the behavior?
A similar question was asked before:
Yet the answer seems to refer specifically to the C11 draft and may not hold for more recent versions of the C Standard as the wording of the informative Annex C has changed since the C11 draft and does not seem fully consistent with the Standard text either.
EDIT: of course such an initializer seems uselessly contorted. I definitely do not condone such programming style and constructions. The question arose from a discussion regarding a trivial definition: int res = 0, a = res; for which the behavior did not seem fully defined (!). Initializers with side effects are not so uncommon, consider for example this one: int arg1 = pop(), arg2 = pop();
Yes, because C 2018 6.8 3 says these initializations (not all, see bottom) are evaluated in the order they appear:
Also, 6.8 4 tells us that each initializer is a full expression and there is a sequence point after the evaluation of a full expression and evaluation of the next:
Given both the above, the initializers are sequenced in the order they appear.
ais initialized first and so has a value whena++is evaluated forb, and the side effects for that are completed before thea++forcbegins, so the whole declaration is safe from the “unsequenced effects” rule in 6.5 2.6.8 3 is a bit lacking for two reasons:
Also note that not all initializers are evaluated in the order they appear in a declaration. 6.7.9 23 discusses initializers for aggregates and unions and says:
History
The wording in 6.8 3 quoted above goes back to C 1999. In C 1990, it had this form in 6.6.2, which is about compound statements: