字符串的静态存储持续时间

Static storage duration for a string

正在测试以下内容:

char* x = "Hello";
printf("%s %p %p %p", "Hello", x, "Hello", "Hello");

Hello
0x5618b7d478c7
0x5618b7d478c7
0x5618b7d478c7

我注意到 "Hello" 在所有情况下都具有相同的内存地址,这意味着编译器将字符串 "Hello" 存储在 .rodata 中一次(应该如此)。

语言规范的这一部分是否是因为无论何时使用字符串文字,都应该在存储之前查找它是否已经存在?或者这是否被认为是不存储重复字符串的编译器优化?

允许编译器对字符串和复合文字进行此类优化。只要它们的值正确地呈现给应用程序,它们就可以共享存储。但另一方面也没有义务这样做。

其他的对象,变量,即使内容相同,也都保证占用自己的存储空间,这样所有这些对象都有一个唯一的地址。

关于为字符串文字创建的数组,C 2018 6.4.5 7 说:

It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

这意味着编译器可以根据其设计者的选择,对相同的字符串使用相同或不同的内存。这包括作为其他字符串的子字符串的字符串,例如 "world""Hello world".

一般来说,行为取决于编译器选项。您可以设置编译器将相同的字符串文字存储为一个字符串文字或不同的字符串文字。

所以你不应该在这样的情况下转播

if ( "Hello" == "Hello" )

它将被评估为 true。

根据 C 标准(6.4.5 字符串文字)

7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

是的,它被认为是编译器优化。它被命名为 string interning. On GCC, it is enabled by -fmerge-constants.