临时对象中的字符串文字?

String Literal in the temporary object?

我是 C++ 及其底层的初学者(与 Python 等相比)。我在 Whosebug 上读到字符串文字进入只读数据部分 (String literals: Where do they go?),但目前我正在阅读一本 C++ 书(作者 Bjarne Stroustrup),里面写到临时对象的生命结束于表达式的结尾,所以:

string var1 = "Hello ";  
string var2 = "World";
string var3 = var1 + var2; // string temp = "Hello World" and assign it to var3

执行后,我们会留下两个 "Hello World"还是只剩下一个个副本?

硬件:

OS: Windows 11;    
Compiler: MSVC;  
Standard: C++11

我知道它可能是实现定义的,但如果是这样,请针对 x86 平台指定。

字符串文字是用语法

专门引用的对象
"Hello "

"World"

这就是 literal 的意思,一个值的原子语法。它一般不指字符串值。

字符串文字不是临时对象。它们是以未指定的方式存储的对象(实际上,如您所指出的,通常在 read-only 内存中)并且具有 静态存储持续时间 ,这意味着它们在完整的持续时间内存在程序执行。


当你写作时

string var1 = "Hello ";

您正在创建一个 std::string 对象,该对象是从字符串文字初始化的。它本身既不是字符串文字,也不保存或引用字符串文字。它会简单地将文字中的字符复制到它自己管理的一些存储中。 var1 对象(如果在块范围内声明,即在函数内)具有 自动存储持续时间 ,这意味着它一直存在到声明它的范围结束为止。


string var3 = var1 + var2;

用于(在 C++17 之前)创建临时 std::string 对象,该对象由 + return 编辑std::string 的运算符重载。然后 var3 是来自这个临时文件的 move-constructed。 var1 + var2 产生的临时值将一直存在到 完整表达式的末尾 ,这意味着直到 var3 的初始化完成。

但是,从 C++17 开始,这里不再涉及临时变量。相反,+ 运算符重载将直接构造 var3 对象。在 C++17 之前,这也被允许发生,因为 so-called return 值优化.


因此,在您的代码中,不存在任何 "Hello World" 字符串文字,但恰好存在一个包含字符 Hello Worldstring 对象,如果您是使用 pre-C++17 版本,可能 还有一个临时 std::string 对象,它具有相同的值,但在 [=19 初始化后被销毁=].