你好请考虑下面的代码片段,在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'。)
文本段是只读的,所以通过将常量放在文本段中,编译器确保它是真正的常量。 它必须存储在某个地方,因为它被声明为可以被其他目标文件访问,所以选择就是数据和文本片段。
如果它是一个静态变量,编译器可能会消除它,因为它是未使用的,无论是否是常量。 如果它是静态的并且是常量,那么编译器可能会将其消除,而不是在其生成的代码中使用它的值。
我要回到我以前的编辑。 我相信,因为它不能改变它的简单的编译器优化,因为它们不能改变,所以不在数据段中存储常量。