根据C++标准,这种对临时的访问是否安全?

问题描述 投票:0回答:1

我最近在 C++ 代码库中发现了以下代码模式,我现在想知道根据 C++ 标准它是否安全。 (真正的代码通过几个函数层传递

const char*
指针,但我将其压缩为其基本形式。)

#include <string>

class NetworkSocket
{
public:
    void SetPort(const char* port)
    {
        m_port = port;
    }

private:
    std::string m_port;
};

int main()
{
    const int     port   = 42;
    NetworkSocket socket = {};

    socket.SetPort(std::to_string(port).c_str());
}

具体来说,我想知道对

SetPort()
的调用是否安全,或者我们是否正在调用未定义的行为,或者访问(可能)已删除的内存。

我尝试使用 cppreference 自己解决这个问题,但陷入了定义中。我到目前为止:

  1. std::to_string()
    返回一个prvalue,从而创建一个临时对象。
  2. c_str()
    的调用延长了临时对象的生命周期。 (至少从 C++17 开始,在我不确定之前。
  3. 从现在开始我就不确定了。看来临时的生命周期到此结束,使得对
    const char*
    指针的访问成为未定义的行为。然而,当我尝试通过 clang 的未定义行为消毒器运行代码时,没有发现任何问题...... https://godbolt.org/z/EfcvePoWe

请引用相关标准规则,并说明标准版本之间的差异(如有)。

c++ language-lawyer lifetime temporary-objects
1个回答
0
投票

这是明确定义的。

12.2 临时对象 [class.temporary]

... 临时对象被销毁作为评估完整的最后一步 表达式 ([intro.execution]) (词法上)包含以下点: 他们被创造了。

这里:

socket.SetPort(std::to_string(port).c_str());

临时对象是

std::string
对象,它是
std::to_string
的返回值。毫无疑问,完整的表达式就是整个表达式。因此,临时对象(拥有其
c_str()
的对象)在对
SetPort()
的调用返回后被销毁。结局。

(此规则有两个例外,它们不适用于此处)。

© www.soinside.com 2019 - 2024. All rights reserved.