c – 引用临时变量 – 为什么编译器没有检测到它?
作者:互联网
我希望这不是重复,我已经阅读了一些相关的问题,但似乎没有人涵盖这个案例:
#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;
}
我认为这是两个相同的未定义行为的情况.输出是1233而我(天真?)预期1234.
所以我的问题是:为什么编译器在第二种情况下没有抱怨,为什么堆栈不像12的情况那样被重写?我错过了什么吗?
(MinGW 4.5.2,-Wall -Wextra -pedantic)
编辑:我知道讨论UB的输出毫无意义.我主要担心的是,如果有更深层次的原因可以解释为什么编译器会检测到一个而另一个没有.
解决方法:
我不确定编译器为什么不抱怨.我想这不是一个非常常见的用例,所以编译器的作者并不认为会为它添加警告.
在调用未定义的行为时,您无法推断出有关行为的任何有用信息.最终的输出可能是3,可能是4,或者可能是其他东西.
[如果你想要一个解释,我建议看一下编译器生成的汇编程序.如果我不得不猜测,我会说编译器完全优化了最后的if(true){…}.
标签:c,undefined-behavior,compiler-warnings 来源: https://codeday.me/bug/20190826/1733465.html