First, to clear things about the storage duration of an automatic local variable, let me quote the C11
standard, chapter §6.2.4, (emphasis mine)
An object whose identifier is declared with no linkage and without the storage-class
specifier static
has automatic storage duration, [...]
and,
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. (Entering an enclosed block or calling a function suspends, but does not end,
execution of the current block.) If the block is entered recursively, a new instance of the
object is created each time. The initial value of the object is indeterminate.
So, in your code, each iteration gets a new instance of j
. Nothing is retained.
In your code,
int j; //not initialized
if(i)
printf("%d ",j); //this one here
you're trying to use an unitialized automatic local variable j
, which has indeterminate value. It invokes undefined behavior.
As per C11
, chapter §6.7.9
If an object that has automatic storage duration is not initialized explicitly, its value is
indeterminate
and related, for UB, annex §J.2
The value of an object with automatic storage duration is used while it is
indeterminate.
Once your code hits UB, the output cannot be justified, anyway.
OTOH, when you declare j
outside the loop, it has function scope. Then, unlike above case, there will be only one instance of j
for all iterations of the loop.
As per the execution flow, first time, i
being 0, if
will evaluate to false, printf()
will be skipped and j
will get initialized. Then, in next iteration, when you hit the printf()
, j
is initialized and it's all well thereafter.