returning const references to temporaries/local variables

Axel Freyn axel-freyn@gmx.de
Tue Jul 6 17:26:00 GMT 2010


Hi,
On Tue, Jul 06, 2010 at 04:44:41PM +0200, Joachim Reichel wrote:
> Hi,
>
> is returning const references to temporaries/local variables always an  
> error (assuming the variable is local, not static, and not a member  
> variable)? Why does g++ only generate warnings, not errors? Because it  
> is legal C++, but not useful? Or undefined behavior?
I think, striktly spoken it's legal C++, but І don't see any useful
situations:  
 - returning the reference to a temporary/local variable in a function
   is perfectly fine and well-defined.
 - however, accessing this reference once the function is finished
   results in undefined behaviour (as the variables are already
   destroyed, and their memory addresses might be re-used for something
   else...)
However, maybe there is a use case? ;-)
You can check it quite easily also by running an example program:

struct Base1 {
  virtual ~Base1(){ std::cout << "destructor Base1 " << this << std::endl;}
};
struct Derived1 : public Base1 {
  ~Derived1(){ std::cout << "destructor Derived1 " << this << std::endl;}
};

const Base1& f1() { Base1 x; return x; }
const Base1& f2() { return Base1(); }
const Base1& f3() { Derived1 x; return x; }
const Base1& f4() { return Derived1(); }

// the same for f5 to b8

int main()
{
  {
    const Base1 & x = f1();
    std::cout << "function 1 finished " << &x << std::endl;
  }
  // and the same for all other functions
}
Here, I print messages whenever an object is destroyed. It results on my
machine in: 

destructor Base1 0xbfc7c2a0
function 1 finished 0xbfc7c2a0

So clearly, the object created by f1 is already destroyed when the code
arrives at the line "function 1 finished" -- you shouldn't use it
anymore;-)
However, you can get the memory address where it WAS stored...

>
> BTW g++ generates a warning for all cases except the last one. I guess  
> there should be a warning as well or am I missing something?
Yes, I think there could (or should) be also a warning for the last
situation -- also there, my code says:

destructor Derived2 0xbfc7c29c
destructor Base2 0xbfc7c29c
function 8 finished

HTH,

Axel



More information about the Gcc-help mailing list