I hope this is not a duplicate, I've read a number of related questions but no one seemed to cover this case:
#include <iostream>
int* return_dangling_p()
{
int x = 1;
return &x; // warning: address of local variable 'x' returned
}
void some_func()
{
int x = 2;
}
int main(int argc, char** argv)
{
// UB 1
int* p = return_dangling_p();
std::cout << *p; // 1
some_func();
std::cout << *p; // 2, some_func() wrote over the memory
// UB 2
if (true) {
int x = 3;
p = &x; // why does compiler not warn about this?
}
std::cout << *p; // 3
if (true) {
int x = 4;
}
std::cout << *p; // 3, why not 4?
return 0;
}
I thought these are two cases of the same undefined behaviour. The output is 1233 while I (naively?) expected 1234.
So my question is: why doesn't compiler complain in the second case and why the stack isn't rewritten like in the case of 12? Am I missing something?
(MinGW 4.5.2, -Wall -Wextra -pedantic)
EDIT: I'm aware that it's pointless to discuss outputs of UB. My main concern was if there's any deeper reason to why one is detected by the compiler and the other isn't.
I'm not sure why the compiler doesn't complain. I suppose it's not a very common use-case, so the compiler authors didn't think to add a warning for it.
You can't infer anything useful about behaviour you observe when you are invoking undefined behaviour. The final output could have been 3, it could have been 4, or it could have been something else.
[If you want an explanation, I suggest look at the assembler that the compiler produced. If I had to guess, I'd say that the compiler optimised the final if (true) { ... } away entirely.]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With