在c中,有哪些规则可以控制编译器如何将相同的字符串合并到可执行文件中

时间:2013-06-28 17:04:41

标签: c compiler-construction

我试图找到c和c ++编译器的规则是什么,将字符串放入可执行文件的数据部分并且不知道在哪里查看。我想知道以下所有地址在c / c ++中是否符合规范:

char * test1 = "hello";
const char * test2 = "hello";
static char * test3 = "hello";
static const char * test4 = "hello";
extern const char * test5; // Defined in another compilation unit as "hello"
extern const char * test6; // Defined in another shared object as "hello"

在Windows上进行测试,它们都是一样的。但是我不知道它们是否适用于所有操作系统。

4 个答案:

答案 0 :(得分:8)

我想知道以下所有内容的地址是否在c / c ++中保证是相同的

允许字符串文字是同一个对象,但不是必需的。

C ++说:

  

(C ++ 11,2.14.5p12)“是否所有字符串文字都是不同的(即存储在非重叠对象中)是实现定义的。尝试修改字符串文字的效果是未定义的。”

C说:

  

(C11,6.5.2.5p7)“字符串文字和具有const限定类型的复合文字,不需要指定不同的对象.1101)这允许实现共享存储的字符串文字和常量复合文字具有相同或重叠表示“

而C99理由说:

  

“此规范允许实现共享具有相同文本的字符串副本,将字符串文字放在只读内存中,并执行某些优化”

答案 1 :(得分:1)

首先,这与操作系统无关。它完全取决于实现,即编译器。

其次,在这种情况下,您可以希望的唯一“保证”将来自编译器文档。语言的正式规则既不保证它们是相同的,也不保证它们是不同的。 (后者适用于C和C ++。)

第三,一些编译器具有诸如“make string literals modifiable”之类的奇怪选项。这通常意味着每个文字都分配在一个独特的存储区域中,并具有唯一的地址。

答案 2 :(得分:0)

他们都可以是一样的。即使以下xy也可以相同。 z可以与y

重叠
const char *x = "hello";
const char *y = "hello\0folks";
const char *z = "folks";

答案 3 :(得分:0)

在C中,我认为关于字符串文字的唯一保证是它将评估为指向内存的可读区域的指针,假定程序不参与未定义的行为,则始终包含指示的字符,后跟一个零字节。允许编译器和链接器以他们认为适合的任何方式协同工作。虽然我不知道有任何编译器/链接器系统这样做,但是编译器将每个字符串文字放在它自己的常量部分中,并且链接器以相反的长度顺序放置这些部分是完全合理的,并且在放置每个之前检查是否已经在某处放置了适当的字节序列。请注意,字节序列甚至不必是字符串文字或定义的常量;如果链接器试图放置字符串"Hi!"并且它注意到机器代码包含字节序列[0x48,0x69,0x21,0x00],则文字可以评估为指向第一个字节的指针。

请注意,写入字符串文字指向的内存是Undefined Behavior。在各种系统上,写入可能陷阱,什么也不做,或只影响文字书写,但它也可能产生完全不可预测的后果[例如,如果文字评估为指向某些机器代码的指针]。