I'm pretty confused about N2346::6.5.2.5/15
and N2346::6.5.2.5/16
which states (emp. mine)
15 EXAMPLE 8 Each compound literal creates only a single object in a given scope
struct s { int i; }; int f (void) { struct s *p = 0, *q; int j = 0; again: q = p, p = &((struct s){ j++ }); if (j < 2) goto again; return p == q && q->i == 1; }
The function f() always returns the value 1.
16 Note that if an iteration statement were used instead of an explicit goto and a labeled statement, the lifetime of the unnamed object would be the body of the loop only, and on entry next time around p would have an indeterminate value, which would result in undefined behavior.
The quote appeared to me as a contradiction to another part of the Standard. Precisely:
N2346::6.5.2.5/5
If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.
meaning that block-scoped object created with compound literals have automatic storage duration.
N2346::6.8/3
(emp. mine):
The initializers of objects that have automatic storage duration, and the variable length array declarators of ordinary identifiers with block scope, are evaluated and the values are stored in the objects (including storing an indeterminate value in objects without an initializer) each time the declaration is reached in the order of execution, as if it were a statement, and within each declaration in the order that declarators appear.
So even if the goto
statement in the example of N2346::6.5.2.5/15
is replaced with an iteration statement the object created by compound literal should be re-created each time it's reached.
QUESTION: Why does replacing goto
with an iteration statement yields UB? What's wrong with my reasoning?