常量局部变量数组在内存中用于’C’程序

我正在使用GCC 4.8.1,它似乎没有将const变量本地存储在DATA段中的main。 下面是3个这样的程序的代码和内存映射:

代码1:

int main(void) { //char a[10]="HELLO"; //1 //const char a[10] = "HELLO"; //2 return 0; } MEMORY MAP FOR ABOVE: text data bss dec hex filename 7264 1688 1040 9992 2708 a.exe 

代码2:

 int main(void) { char a[10]="HELLO"; //const char a[10] = "HELLO"; return 0; } MEMORY MAP FOR 2: text data bss dec hex filename 7280 1688 1040 10008 2718 a.exe 

代码3:

 int main(void) { //char a[10]="HELLO"; const char a[10] = "HELLO"; return 0; } MEMORY MAP FOR 3 : text data bss dec hex filename 7280 1688 1040 10008 2718 a.exe 

我没有看到3个代码之间的数据段有任何差异。 有人可以向我解释这个结果。

在期待中感谢!

这是应该发生的事情:

代码1:任何地方都没有存储。

代码2: a存储在堆栈中。 它不存储在.data

代码3a要么存储在堆栈中,要么存储在.rodata ,具体取决于它是否使用常量表达式进行初始化。 优化器也可能决定将其存储在.text (与代码一起)。

我没有看到3个代码之间的数据段有任何差异。

那是因为应该没有区别。 .data用于具有静态存储持续时间的非常量变量,初始化为非零值。

如果程序不使用您的数组,则允许编译器简单地优化对象。

从C标准:

(C99,5.1.2.3p1)“本国际标准中的语义描述描述了抽象机器的行为,其中优化问题无关紧要”

(C99,5.1.2.3p3)“在抽象机器中,所有表达式都按语义指定进行评估。实际实现不需要评估表达式的一部分,如果它可以推断出它的值没有被使用而且没有必要的副作用生成(包括通过调用函数或访问volatile对象而导致的任何内容)。“

如果编译程序#3并禁用优化( -O0 )或依赖于编译器,仍然可以分配对象。 在您的情况下,它不会出现在datarodata部分中,而是出现在text部分中,因此text部分会增加。

例如,在您的第三个示例中,在我的编译器中,使用-O0生成的代码(使用objdump -d转储):

 00000000004004d0 
: 4004d0: 55 push %rbp 4004d1: 48 89 e5 mov %rsp,%rbp 4004d4: 48 b8 48 45 4c 4c 4f mov $0x4f4c4c4548,%rax 4004db: 00 00 00 4004de: 48 89 45 f0 mov %rax,-0x10(%rbp) 4004e2: 66 c7 45 f8 00 00 movw $0x0,-0x8(%rbp) 4004e8: b8 00 00 00 00 mov $0x0,%eax 4004ed: 5d pop %rbp 4004ee: c3 retq 4004ef: 90 nop

0x4f4c4c4548是在字符串中移动的字符串的ASCII字符,然后在堆栈中推送。

如果我用-O3编译相同的程序,输出就是:

 00000000004004d0 
: 4004d0: 31 c0 xor %eax,%eax 4004d2: c3 retq 4004d3: 90 nop

并且字符串不会出现在datarodata ,只是简单地优化了。