警告 C4172:返回对绑定到局部变量的 const std::string 的引用。安全性如何?

发布于 2024-11-29 09:35:21 字数 365 浏览 1 评论 0原文

我刚刚在工作中构建一个项目,我看到添加了一个新函数:

const std::string& ClassName::MethodName() const
{
   return "";
}

编译器发出警告:

警告 C4172:返回局部变量或临时变量的地址

我认为编译器是正确的。 这个函数的安全性如何?

请注意,该函数不会返回 const char* ,因为字符串文字具有静态存储持续时间,所以这是可以的。它返回对 const std::string 的引用

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

泅渡 2024-12-06 09:35:21

是的,这不安全。
返回局部变量或临时变量的地址并取消引用它会导致未定义的行为。

正如您评论的那样:
是的,临时绑定到常量引用的生命周期会增加,直到常量的生命周期为止。但这需要调用者接受 const 引用中的返回值,因此该函数本身并不安全。

来自 C++ 标准:
C++03 12.2 临时对象

第二个上下文是引用绑定到临时对象时。引用所绑定到的临时对象,或者是临时对象所绑定的子对象的完整对象的临时对象在引用的生命周期内持续存在,除非下面指定...

构造函数构造函数初始化程序 (12.6.2) 中引用成员的临时绑定将持续存在,直到构造函数退出。临时绑定到引用
函数调用 (5.2.2) 中的参数一直持续到包含调用的完整表达式完成为止。函数返回语句 (6.6.3) 中返回值的临时绑定一直持续到函数退出

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

命比纸薄 2024-12-06 09:35:21

这是一个让我明白事情的例子:

#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";
}

输出

Ctor
Dtor
1
Ctor
2
Dtor
3

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
年华零落成诗 2024-12-06 09:35:21

执行您所做的操作实际上是在编译器内部执行此操作:

const std::string* ClassName::MethodName() const
{
   std::string temp = "";
   return &temp;
}

返回对局部变量的引用或指针是不好的。

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.

苍景流年 2024-12-06 09:35:21

在某些情况下此代码是安全的。请参阅 GotW #88:A “最重要的常量”的候选人

There are circumstances when this code is safe. See GotW #88: A Candidate For the “Most Important const”.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文