There are several questions about lifetime of constant reference on SO, but still I don't get it.
Is this piece of code valid?
struct S
{
const int &ref;
S( const int &x ) : ref(x) { }
};
int main( )
{
S s( 0 );
// ...
use( s.ref );
// ...
return 0;
}
Intuitively I'd say no, since 0
should expire after the expression (S s(0);
) is evaluated.
However both GCC and CLANG compile it fine, without warnings, and valgrind doesn't detect any runtime error.
What am I missing about references?
Here is another tweak to your code that even valgrind complains about:
This normally puts the temporary in the stack frame of the
foo
function, so it gets destroyed when that function returns. This is similar to returning the address of a local variable.The other answers have pointed out why the compiler is allowed to do this, my code is just an illustration.
As others have pointer out, the C++ standard only forces the compiler to keep the
0
temporary around for the duration for calling the constructor. In practice gcc keeps the temporary around for the duration of themain
function which results in the program running as expected. For this reason, there are no warnings or runtime errors.But this only works accidentally. Don't rely on this behaviour.
0
isn't a temporary, it's a literal. Try this small change to your program:I think the rule for references to a temporary only works for local variables, not members.
The thing to note here is not the
const
but the reference. The const is just a tool for static analysis. You need to be careful with references because they can bite.Sometimes the compiler is smart enough to warn you about issues that would show up at run time, but sometimes it's not. Either way the compiler doesn't have to warn you about this.
Seems invalid to me according to 12.2/4 :
The temporary only gets to live until
s
is fully constructed, not until the point whereuse
is called.