提问人:einpoklum 提问时间:10/20/2022 最后编辑:einpoklum 更新时间:10/20/2022 访问量:80
为什么 GCC 不警告我存储对局部变量的引用?
Why doesn't GCC warn me about storing a reference to a local variable?
问:
假设我正在编译以下代码:
struct foo {
const int& x_;
foo(const int x) : x_(x) { }
};
int main()
{
int x = 1;
auto b2 = foo{x};
return b2.x_;
}
这个程序有未定义(或实现定义?)的行为 - 成员引用是用对变量的引用初始化的,该变量是 的构造函数的局部变量,并且在构造对象存在时超出范围。因此,取消引用无效引用。x_
x
foo
foo
b2.x_
现在,我希望编译器会警告我这一点。对对象和构造函数的本地分析足以意识到这种情况正在发生。但是 - 当我编译这个程序时 - 我没有收到任何警告。怎么会这样?g++ -W -Wall -Wextra
注意:我的 GCC 版本是 7.4.1。
答:
1赞
einpoklum
10/20/2022
#1
未能警告用户这种情况是 GCC <= 7.x 的“错误功能”——但它已经在 8.x 版本中“修复”了,它已经为您提供了一些东西:
<source>:6:5: warning: 'x' is used uninitialized [-Wuninitialized]
6 | int main()
| ^~~~
不过,这不是一个非常有用的警告。使用最新版本的 GCC,例如 12.x,您可以获得:
<source>: In constructor 'foo::foo(int)':
<source>:3:24: warning: storing the address of local variable 'x' in '*this.foo::x_' [-Wdangling-pointer=]
3 | foo(const int x) : x_(x) { }
| ^~~~~
<source>:3:19: note: 'x' declared here
3 | foo(const int x) : x_(x) { }
| ~~~~~~~~~~^
<source>:3:19: note: '<unknown>' declared here
<source>: In function 'int main()':
<source>:6:5: warning: 'x' is used uninitialized [-Wuninitialized]
6 | int main()
| ^~~~
虽然第二个警告不是那么有用,但第一个警告是正确的。
在 Godbolt 上看到这个。
评论