Warning: Returning Reference to Temporary

warning: returning reference to temporary

This is an example when an unwanted implicit conversion takes place. "" is not a std::string, so the compiler tries to find a way to turn it into one. And by using the string( const char* str ) constructor it succeeds in that attempt.
Now a temporary instance of std::string has been created that will be deleted at the end of the method call. Thus it's obviously not a good idea to reference an instance that won't exist anymore after the method call.

I'd suggest you either change the return type to const string or store the "" in a member or static variable of SomeClass.

Why am I getting warning: returning reference to local temporary object?

That is because the SpecialId and OtherId are uint32_t, and since your function returns int it must be implicitly cast so a temporary is created.

Either change the return types of Full_Coord::r and Full_Coord::ls to SpecialId and OtherId respectively, or use auto as a return type.

auto const& r() const { return xy_r.r(); }
auto const& ls() const { return ls_; }

Warning: returning reference to local temporary object

No, "returning a reference" does not magically extend any lifetime.

The only time that lifetime is extended is when a prvalue (or an xvalue referring to a member of a prvalue) is bound to a reference variable, and the lifetime of the prvalue is extended to that of the variable:

struct Foo{};

{
const auto & r = Foo{}; // Foo object not destroyed at semicolon...
// ...
}
// ... but is destroyed only here.

Your prvalue is not bound to any variable, and hence no lifetime is extended.

(Also note that non-static class data members don't count as "variables" for this consideration, so you also can't extend lifetimes via constructor initializer lists if your class happens to have reference members.)

returning reference to temporary object

The life time of a temporary object is extended only in some contexts. The example in the posted code is not one of those contexts.

int foo() { return 10; }

...

int const& x = foo(); // Life of the temporary is extended.

However,

const int& foo() { return 10; } // Life of the temporary is not extended.

...

int const& x = foo(); // Dangling reference.

Your posted code is analogous to

const int& foo(int const& in) { return in; }

...

int const& x = foo(10);

Here, the reference is valid only inside foo. Once foo returns, the object is not alive any longer, and the reference becomes a dangling reference.

Why I get the following error: returning reference to temporary [-Werror=return-local-addr]

The set<...>::begin function returns its iterator by value. Since you do not store that value anywhere, it's a temporary value, and you can't really have references to temporary values.

The simple solution is for your function to also return by (non-const) value.

Warning: returning reference to temporary - strange case (Clarification for Rvalue)

return 2*i; does not multiply 2 by i and store that result into i. It multiples 2 by i and puts that result into a temporary. Trying to return that temporary by reference is a no go as it is destroyed at the end of that line. lifetime extension does not apply here.

If you want to modify i and return it you need to use operator *= which will modify i and give you a reference to it that you can return like

return i *= 2;

But fun would need to take a int& instead of const int &.


If you want to return an rvalue then what you do is return by value like:

int fun(const int &i)
{
return 2*i;
}

and now you can capture it like:

int main()
{
const int& ret = fun(3);
cout << ret << endl;
return 0;
}

Why is the returning reference to temporary object compiler warning not triggered?

It looks like it is a bug in Visual Studio, you can find it was reported for VS 2012 and it appears it was still present in 2013:

https://connect.microsoft.com/VisualStudio/feedback/details/776530/warning-c4172-not-emitted

Above link might be a duplicate of some other, the example from this bug report looks quite the same as your sample code:

// main.cpp

struct A
{
};

struct B
{
A a() const {return A();}
};

struct C
{
A const& a() const
{
return B().a();
}
};

int main()
{
return 0;
}


Related Topics



Leave a reply



Submit