为什么常量存储在C内存映射的文本段中?

你好请考虑下面的代码片段,在Linux机器(64位)上用gcc编译,并带有相应的内存映射

#include <stdio.h> int global = 2; int main(void) { int local = 0; return 0; } text data bss dec hex filename 1092 500 16 1608 648 mem 

这里有一个全局variables初始化为2。 它被存储在数据段中考虑使其为const的情况,如下所示

 #include <stdio.h> int const global = 2; int main(void) { int local = 0; return 0; } text data bss dec hex filename 1096 496 16 1608 648 mem 

这里全局variables从数据段移到文本段。

为什么它从数据移动到文本段?

由于数据段分为读取和读写区,它应该已经存储在数据的读取区中了吗?

在代码中间初始化一个未初始化的全局variables会发生什么?

在现代系统中,常量保留在只读数据的目标文件的一部分。 该部分通过默认模式下的size命令与“text”(程序代码)部分混合在一起,但是您可以让它给出更多的细节:

 $ size test.o # compiled from the code in the question text data bss dec hex filename 58 0 0 58 3a test.o $ size -A test.o test.o : section size addr .text 6 0 .data 0 0 .bss 0 0 .rodata 4 0 .comment 29 0 .note.GNU-stack 0 0 .eh_frame 48 0 Total 87 

看看第一个命令产生的“文本”数字是如何由第二个问题产生的.text.rodata.eh_frame数字的总和?

你可以通过objdump命令知道常量在.rodata而不是.text

 $ objdump -t test.o | grep -w global 0000000000000000 g O .rodata 0000000000000004 global 

('g'代表全局,'O'代表'Object',Function代表'F'。)

文本段是只读的,所以通过将常量放在文本段中,编译器确保它是真正的常量。 它必须存储在某个地方,因为它被声明为可以被其他目标文件访问,所以选择就是数据和文本片段。

如果它是一个静态变量,编译器可能会消除它,因为它是未使用的,无论是否是常量。 如果它是静态的并且是常量,那么编译器可能会将其消除,而不是在其生成的代码中使用它的值。

我要回到我以前的编辑。 我相信,因为它不能改变它的简单的编译器优化,因为它们不能改变,所以不在数据段中存储常量。