This is well-defined behavior.
According to the C Standard §6.2.4 (emphasis mine):
An object exists, has a constant address, and retains its last-stored value throughout its lifetime.
The lifetime of the non-static struct begins with the entry into the block in which it is declared (known as automatic storage duration):
For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way.
And if, in the block with which the declaration is associated, you specify an initialization:
[the initialization] is performed each time the declaration is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached.
So upon entering the block, the struct has guaranteed storage and a constant address that you are free to use in an initialization for that struct, since the initialization is guaranteed to happen after the lifetime of the struct has started.
For the static struct,
Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
So the struct has guaranteed storage and a constant address as soon as program execution starts, and its stored value is initialized during that lifetime but prior to the standard execution protocol (calling main()
, etc).
Source: C99 draft. The C11 literature for these references is identical.
Here's a demo. This compiles without warnings under -std=c99 -pedantic
and -std=c11 -pedantic
.