【发布时间】:2016-09-19 18:40:35
【问题描述】:
我编写了以下代码,输出45:
#include <iostream>
int main()
{
int *p;
{
int n = 45;
p = &n;
}
std::cout << *p;
}
因为n 的生命周期在我预期此代码会发出错误或警告的范围内结束。使用 GCC 6.1.0 和 Clang 3.8.0 以及 libubsan sanitizer 我没有得到任何提示。
g++ -Wall -Wextra -pedantic -fsanitize=undefined
clang++ -Weverything -fsanitize=undefined
Valgrind 也不抱怨。如果我查看程序集,GCC 只是重用了堆栈中的相同值:
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
我知道尊重 NULL 指针是未定义的行为,但是悬空指针呢? (如果是未定义的行为,请提供标准中的引用。)
我希望有人证明这是未定义的行为,而不仅仅是说它没有证据。 duplicate 有很多未引用声明的答案。在 C 中,它明确表示“在其生命周期之外使用对象”是未定义的行为。在 C++ 中,情况并非如此。事实上,§3.8 似乎并没有说任何直接的东西。
请重新打开我的问题,这样我才能得到一些实际的证据,而不是货真价实。
【问题讨论】:
-
看看这个。 stackoverflow.com/questions/13888268/… 几乎是同一个问题。
-
函数级变量的生命周期是函数调用的持续时间。可见性仅限于声明范围,但生命周期并非如此。
-
将
-O添加到您的标志中,您应该会收到警告。 -
@user6369079 stackoverflow.com/questions/6441218/… 呢?
-
@Barry Read this 回复我。
标签: c++ undefined-behavior dangling-pointer