Yes it is undefined, but the behaviour you observe is not necessarily surprising; it is just that the stack is reused and the reused space is not initialised, and you happened to have reused exactly the same stack location as the previous call. All memory has to contain something and if you call this function and it happens to re-use the same stack frame as a previous call, it will contain whatever was last left there.
For example if you call:
Func() ;
Func() :
It is not defined, but not unreasonable for the second call fooStruct.foo
to contain the value left by the first call, because that is what would happen when the compiler takes no action to initialise the variable.
However if instead you had:
void Func2()
{
int x = 0 ;
int y = 0 ;
Func() ;
}
Then called:
Func() ;
Func2() ;
The second call to Func()
via Func2()
would almost certainly place the local fooStruct.foo
at a different address within the stack because of the stack frame for Func2
, so would not then have the same value other then by coincidence. Moreover if the sequence were:
Func() ;
Func2() ;
Func() ;
The third call to Func()
might use the same stack location as the first, but that space will probably have been modified by Func2()
(because of the initialised variables), so likely you will no longer observe the same value in fooStruct.foo
.
That is what uninitialised means; you get whatever happens to be there. And because when a variable goes out of scope, it is not generally modified, such values can "reappear" (and not necessarily in the same variable) - just because that is the simplest and most efficient implementation (i.e. to do nothing).