int main()
{
{int x = 532;}
int xc;
int x = *(&xc 1);
cout << x << endl; // prints 532
}
I create an int variable with a value of 532 and then it immediately goes out of scope. I then create another int variable right after so that it has an address of 1 word before x. I then assign that value of whatever was one word past xc to x and print it, and it has the value of 532. Is this guaranteed to happen? Why/why not?
CodePudding user response:
No, the arrangement and padding (and even the existence) of variables on the stack is implementation-dependent, and what you have here is Undefined Behavior. The language specifies that you must not use a pointer to access the memory of any object other than the one it points to.
In this case, &xc 1
points to memory that lies outside the allocation of xc
. You cannot read or write to this location and expect any kind of predictable result. Note that it is actually a valid pointer -- you are allowed to point "one-past-the-end" of an allocation, provided you never dereference that address.
To explain what's actually happening in your case: your variables are being pushed onto the stack, and the stack memory extends in the direction of lower addresses. It appears your compiler didn't bother to unwind the stack after the original x
went out of scope. Alternatively, multiple values of 532 might have been initialized in memory, or in a register, and the value you're reading might not be the one that was stored at x
. All this said, even this program on your computer with your compiler does not guarantee this behavior.
- The original variable
x
could be optimized away by the compiler completely because it is not used. - The value of
xc
is uninitialized. Its location (if any) on the stack is not guaranteed. Even thoughx
had additional scope, the compiler is not required to push and pop stack locations if it doesn't want to. - The compiler is not required to understand that you're aliasing
x
viaxc
because, as already mentioned such behavior is not defined.