I was taught that variables within scope are destroyed (freed/de-allocated?) at the instruction generated by the "}" at the end of a scope body. I was about to teach someone the same thing, but I decided to see for myself, what will happen if I change a local variable through a pointer like this:
int main ()
{
int* p = NULL;
if(1)
{
int localvar = 1;
p = &localvar;
}
(*p) = 345;
printf("%i\n", *p);
return 0;
}
Compiled with MinGW-GCC and "-Wall -g -pedantic -w -Wfatal-errors -Wextra"
(even though -Wall
overrides most flags)
It was very surprising to me that not only a warning was generated, but also no runtime exception was thrown. Instead, everything seems to work just as if I am accessing a global variable.
Can this be explained in a definitive manner to avoid any future misconceptions?
C compilers aren't required to generate an error when you do something like this. That's part of what makes C fast.
That also means that if you do something you're not supposed to do, you can trigger undefined behavior. This essentially means that no guarantees can be made regarding what the program will do. It could crash, it could output strange results, or it could appear to be work properly as in your case.
How UB manifests itself can change by making a seemingly unrelated change, such as adding an unused local variable or a call to printf
for debugging.
In this particular case the memory in question hasn't been reserved for some other use so it is still in the valid memory space for the program and hasn't yet been overwritten. But again, you can't rely on that behavior.