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

kx7yvsdv  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(175)

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

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。

lmvvr0a8

lmvvr0a81#

没有警告用户这种情况是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

相关问题