I wrote the following code which outputs 45
:
#include <iostream>
int main()
{
int *p;
{
int n = 45;
p = &n;
}
std::cout << *p;
}
Because the lifetime of n
ends at the scope I expected this code to emit an error or warning. Using GCC 6.1.0 and Clang 3.8.0 and the libubsan sanitizer I don't get a blip.
g++ -Wall -Wextra -pedantic -fsanitize=undefined
clang++ -Weverything -fsanitize=undefined
Valgrind doesn't complain either. If I look at the assembly, GCC just reuses the same value from the stack:
400789: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax
std::cout << *p;
40078d: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
400791: 8b 00 mov eax,DWORD PTR [rax]
400793: 89 c6 mov esi,eax
400795: bf 60 10 60 00 mov edi,0x601060
40079a: e8 81 fe ff ff call 400620 <std::basic_ostream<char, std::char_traits<char> >::operator<<(int)@plt>
}
std::cout << *p;
40079f: 48 8b 45 f8 mov rax,QWORD PTR [rbp-0x8]
4007a3: 8b 00 mov eax,DWORD PTR [rax]
4007a5: 89 c6 mov esi,eax
4007a7: bf 60 10 60 00 mov edi,0x601060
I know it's undefined behavior to deference a NULL pointer, but what about a dangling pointer? (If it's undefined behavior, please provide quotes from the standard.)
I'd like for someone to prove it's undefined behavior, not just say that it is without proof. The duplicate has a lot of answers that make uncited claims. In C, it explicitly says that "using an object outside its lifetime" is undefined behavior. In C++, this is not the case. In fact, §3.8 doesn't seem to say anything remotely that direct.
Please reopen my question so I can get some actual proof and not cargo culting.