Reputation: 1329
From this thread it is clear that a string literal cannot be used for a function that returns const string& since there is an implicit conversion from const char* to std::string which creates a temporary.
But then why do I get a warning "warning: returning reference to a temporary" if my return type match exactly and there is no need for conversion, e.g.:
include <iostream>
const int& test(){
return 2;
}
int main(){
std::cout << test();
}
No implicit conversion needed to happen on the return value of 2, so why is there a warning? I thought using test() would be pretty much the same as doing
const int& example = 2;
which is perfectly valid. Additionally if I change 2 to 2.2 (so it is a double) the program still runs (with the same warning) despite the fact there IS a conversion from double to int? Shouldn't I be running in to an issue similar to how const char* was returned to the string reference, if there is a conversion from double to int?
Upvotes: 3
Views: 780
Reputation: 23
an implicit conversion from const char* to std::string which creates a temporary
You are conflating the two topics. Implicit conversions are not the only thing that can create temporaries:
const std::string& test() {
return std::string("no implicit conversions here.");
}
There is no implicit conversion to create the string
, but the created string
is still temporary, and so you're still returning a reference to a temporary object.
In your example, 2
is still a temporary value, temporarily stored somewhere on the stack, and whose location/address is returned so callers can get at the value, but they are not supposed to.
Upvotes: 0
Reputation: 60979
A temporary is still created. §8.5.3/(5.2.2.2) applies1:
Otherwise, a temporary of type “ cv1
T1
” is created and copy-initialized (8.5) from the initializer expression. The reference is then bound to the temporary.
This also applies in your second example. It does not apply for prvalues of class type, or scalar xvalues: Both
const A& a = A();
// and
const int& i = std::move(myint);
do not introduce a temporary. However, that isn't changing the final result : In any case, the temporary that is bound to the reference will be destroyed at the end of the return
statement - §12.2/(5.2):
The lifetime of a temporary bound to the returned value in a function
return
statement (6.6.3) is not extended; the temporary is destroyed at the end of the full-expression in thereturn
statement.
That is, the temporary is destroyed before the function even exits, and thus your program induces undefined behavior.
1 I could go on and quote the entire list to show why it does, but that would presumably be a waste of answer space.
Upvotes: 1