Warning C4172: Returning a reference to const std::string bound to a local variable. How safe is it?
I was just building one of our projects at work and I see a new function was added:
const std::string& ClassName::MethodName() const
{
return "";
}
The compiler gives a warning:
Warning C4172: returning address of local variable or temporary
I think the compiler is right. How safe is this function?
Note that the function doesn't return const char*
which would be OK inasmuch as string literals开发者_高级运维 have static storage duration. It returns a reference to const std::string
Yes it is not safe.
Returning address of a local variable or temporary and dereferencing it results in Undefined Behavior.
As you commented:
Yes, the lifetime of the temporary bound to a constant reference increases till the lifetime of constant. But that needs the caller to accept the return value in a const reference, So by itself the function won't be safe.
From the C++ Standard:
C++03 12.2 Temporary objects:
The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below...
A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits. A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full expression containing the call.A temporary bound to the returned value in a function return statement (6.6.3) persists until the function exits
This is an example that made things clear for me:
#include <iostream>
using std::cout;
struct A{
A() {
cout << "Ctor\n";
}
~A() {
cout << "Dtor\n";
}
};
const A& f(){
return A();
}
int main(){
const A& ref = f();
cout << "1\n";
{
const A& ref1 = A();
cout << "2\n";
}
cout << "3\n";
}
Outputs
Ctor
Dtor
1
Ctor
2
Dtor
3
Doing what you did actually does this internally in the compiler:
const std::string* ClassName::MethodName() const
{
std::string temp = "";
return &temp;
}
And returning references or pointers to local variables is bad.
There are circumstances when this code is safe. See GotW #88: A Candidate For the “Most Important const”.
精彩评论