为什么 GCC 不警告我存储对局部变量的引用?

Why doesn't GCC warn me about storing a reference to a local variable?

提问人:einpoklum 提问时间:10/20/2022 最后编辑:einpoklum 更新时间:10/20/2022 访问量:80

问:

假设我正在编译以下代码:

struct foo {
    const int& x_;
    foo(const int x) : x_(x) { }
};

int main()
{
    int x = 1;
    auto b2 = foo{x};
    return b2.x_;
}

这个程序有未定义(或实现定义?)的行为 - 成员引用是用对变量的引用初始化的,该变量是 的构造函数的局部变量,并且在构造对象存在时超出范围。因此,取消引用无效引用。x_xfoofoob2.x_

现在,我希望编译器会警告我这一点。对对象和构造函数的本地分析足以意识到这种情况正在发生。但是 - 当我编译这个程序时 - 我没有收到任何警告。怎么会这样?g++ -W -Wall -Wextra

注意:我的 GCC 版本是 7.4.1。

C++ GCC 参考 clang dangling-pointer

评论


答:

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 上看到这个。