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

98 Views Asked by At

Suppose I'm compiling the following code:

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

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

This program has undefined (or implementation-defined?) behavior - the member reference x_ is initialized with a reference to a variable x, which is local to the constructor of foo, and goes out of scope while the constructed foo object lives on. So b2.x_ dereferences an invalid reference.

Now, I would expect a compiler to warn me about this. Local analysis of the object and the constructor are sufficient to realize this is happening. But - when I compile this program with g++ -W -Wall -Wextra - I get no warnings. How come?

Note: My GCC version is 7.4.1.

1

There are 1 best solutions below

0
einpoklum On

Failing to warn the user about this situation was a "mis-feature" of GCC <= 7.x - but it was "fixed" already in the 8.x release, which already gives you something:

<source>:6:5: warning: 'x' is used uninitialized [-Wuninitialized]
    6 | int main()
      |     ^~~~

not a very useful warning though. with more recent versions of GCC, e.g. 12.x, you get:

<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()
      |     ^~~~

and while the second warnings is not-so-useful, the first one is right on the money.

See this on Godbolt.