When the value of an object with automatic storage duration is reached, and the object is not initialized, the behavior is undefined. This is explicitly and formally stated in N1570 . 6.3.2.1 paragraph 2 (this is the last public draft of ISO C).
"Undefined behavior" means not only that you can get an arbitrary value. This means "behavior when using an intolerable or erroneous software construct or erroneous data for which this International Standard does not impose any requirements" ( N1570 3.4.3). The language standard literally says nothing about what access to such an asset value means. This is effectively pure gibberish. (The standard joke is that undefined behavior can cause demons to fly out of your nose. Of course, this is not possible in real life, but if so, you cannot complain that the compiler does not agree.)
But let it momentarily ignore the undefined behavior of accessing an uninitialized int . Maybe today you are lucky. Perhaps you know how your compiler will handle this case.
More precisely, let us assume some probable assumptions about how undefined behavior might look.
Let's pretend that:
int i; i ++;
Assume that the initial value (undefined) i is INT_MAX . Then the increment i causes an integer overflow of the sign, which is clearly clearly an undefined behavior ( N1570 6.5 clause 5). Even if the initial value is less than INT_MAX , incrementing it enough time will lead to overflow - and since you do not know what the initial value is, you do not know how many times you can "safely" increase it.
The most likely consequence is that the optimizing compiler will transform the code in a way that depends on the assumption that its behavior is defined. Here is an example that does not contain an uninitialized variable:
int i = INT_MAX; int j = i + 1; if (j > i) { }
If an add-on obeys the general semantics of the second add-on (not guaranteed by the C standard, but usually implemented in hardware), then j will be equal to INT_MIN , and (j > i) will be false. Logically, (j > i) must be false, because the value of int can exceed INT_MAX . But since j was set to i + 1 , then (j > i) should be true (for any program that defined the behavior).
Regardless of your expectations regarding the behavior of this code, the optimization compiler may legally violate them. If you are lucky, he may warn you before breaking your code, but this is not required.
You will spend much less time adding = 0 to ad i than we have discussed what will happen if you do not. (But even then you may run into problems if you increase i enough time to cause an overflow.)