What's the behavior of an uninitialized variable used as its own initializer?

  • A+

I noticed just now that the following code can be compiled with clang/gcc/clang++/g++, using c99, c11, c++11 standards.

int main(void) {     int i = i; } 

and even with -Wall -Wextra, none of the compilers even reports warnings.

By modifying the code to int i = i + 1; and with -Wall, they may report:

why.c:2:13: warning: variable 'i' is uninitialized when used within its own initialization [-Wuninitialized]     int i = i + 1;         ~   ^ 1 warning generated. 

My questions:

  • Why is this even allowed by compilers?
  • What does the C/C++ standards say about this? Specifically, what's the behavior of this? UB or implementation dependent?


Because i is uninitialized when use to initialize itself, it has an indeterminate value at that time. An indeterminate value can be either an unspecified value or a trap representation.

If your implementation supports padding bits in integer types and if the indeterminate value in question happens to be a trap representation, then using it results in undefined behavior.

If your implementation does not have padding in integers, then the value is simply unspecified and there is no undefined behavior.


To elaborate further, the behavior can still be undefined if i never has its address taken at some point. This is detailed in section of the C11 standard:

If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.

So if you never take the address of i, then you have undefined behavior. Otherwise, the statements above apply.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: