开发者

Warning C4172: Returning a reference to const std::string bound to a local variable. How safe is it?

开发者 https://www.devze.com 2023-03-27 21:27 出处:网络
I was just building one of our projects at work and I see a new function was added: const std::string& ClassName::MethodName() const

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”.

0

精彩评论

暂无评论...
验证码 换一张
取 消