提问人:jan.sende 提问时间:11/9/2023 最后编辑:jan.sende 更新时间:11/10/2023 访问量:117
根据 C++ 标准,这种对临时访问是否安全?
Is this access to temporary safe according to the C++ standard?
问:
我最近在 C++ 代码库中发现了以下 Code Pattern,我现在想知道根据 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 自己弄清楚,但被困在定义中。我得到了:
std::to_string()
返回一个 PRE值,从而创建一个临时对象。- 调用延长临时的生存期。(至少从 C++17 开始,在我不确定之前。
c_str()
) - 从现在开始,我不确定。临时的生存期似乎到此结束,使得对指针的访问成为未定义的行为。但是,当我尝试通过 clang 的未定义行为清理器运行代码时,没有发现任何问题......https://godbolt.org/z/EfcvePoWe
const char*
请引用相关标准规则,并说明标准版本之间的差异(如果有的话)。
答:
4赞
Sam Varshavchik
11/9/2023
#1
这是明确定义的。
... 临时对象被销毁,作为评估完整对象的最后一步。 表达式 ([intro.execution]) (词法上)包含 他们被创造出来了。
... 完整表达式是不是另一个表达式的子表达式的表达式。
这里:
socket.SetPort(std::to_string(port).c_str());
临时对象是作为 的返回值的对象。不出所料,完整的表达就是整个表达。因此,临时对象 - 拥有它的对象 - 在调用返回后被销毁。结束。std::string
std::to_string
c_str()
SetPort()
(此规则有两个例外,它们在这里不适用)。
评论
c_str()
不会延长寿命,临时字符串在;
private: const char* m_port
std::to_string(port).c_str()
活到尽头,所以你是安全的socket.SetPort(std::to_string(port).c_str());
socket.SetPort(std::to_string(port).c_str())