Const refers to a temporary link

#include <iostream> using namespace std; struct CL { CL() { cout<<"CL()"<<endl; } CL(const CL&) { cout<<"CL(const CL&)"<<endl; } ~CL() { cout<<"~CL()"<<endl; } }; CL cl; CL fnc() { return cl; } int main() { cout<<"start"<<endl; const CL& ref=static_cast<const CL&>(fnc()); //...Is "ref" valid here?? cout<<"end"<<endl; return 0; } 

What is the lifetime of a temporary object returned by fnc ()? Is it the "ref" lifetime or the temporary reference static_cast (fnc ()) that was destroyed at the end of the statement?

Gcc output (fnc () lifetime is the "ref" lifetime):

 CL() //global object "cl" start CL(const CL&) end ~CL() ~CL() //global object "cl" 

VS2013 output (fnc () lifetime - time reference lifetime):

 CL() //global object "cl" start CL(const CL&) ~CL() end ~CL() //global object "cl" 

What is correct by standard?

+7
c ++ reference language-lawyer temporary-objects
source share
1 answer

I believe that Visual Studio is correct here, this is described in bug report # 1376 , which states:

In type declaration

 T&& r = static_cast<T&&>(T()); 

it is not clear what should be the lifetime of temporary T. According to clause 5.2.9 of [expr.static.cast], static_cast is equivalent to the declaration of the invented temporary variable t. the temporary lifetime extends to time t, but it is not clear what this lifetime should be, or if subsequent binding t to r will affect the lifetime of the initial temporary. (See also question 1568.)

and discussion includes this conclusion:

The link is bound to the xvalue result for static_cast, so the temporary lifetime is not extended, and this example causes the link to freeze.

and defect report 1568 describes this case in more detail:

According to 12.2 [class.temporary] paragraphs 4-5,

There are two contexts in which temporary objects are destroyed at a different point than the end of the full expression ...

The second context is when the binding is tied to a temporary one. The temporary to which the link is attached, or the temporary full object of the subobject to which the link is attached is preserved for the duration of the link ...

It is unclear whether this applies to an example of the following:

 struct S { }; const S& r = (const S&)S(); 

and the answer was:

This issue is a duplicate of number 1376.

therefore in this case:

 const CL& ref=static_cast<const CL&>(fnc()); 

the link is tied to the static_cast result, not to the CL , and so CL is a dangling link.

For reference, the corresponding text from the standard section of the C ++ 11 5.2.9 project [expr.static.cast]:

Otherwise, the expression e can be explicitly converted to type T using static_cast of the form static_-cast (e) if the declaration is T t (e); well formed, for some invented time variable t (8.5). the effect of such an explicit conversion is the same as performing a declaration and initialization, and then using a temporary variable as a result of the conversion. The expression e is used as a glvalue if and only if initialization uses it as a glvalue.

+5
source share

All Articles