我正在使用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个代码之间的数据段没有任何差异。有人可以向我解释这个结果。
感谢您的期待!
答案 0 :(得分:10)
如果你的程序没有使用你的数组,那么允许编译器简单地优化对象。
来自C标准:
(C99,5.1.2.3p1)"本国际标准中的语义描述描述了抽象机器的行为,其中优化问题无关紧要"
和
(C99,5.1.2.3p3)"在抽象机器中,所有表达式都按语义指定进行计算。实际实现不需要评估表达式的一部分,如果它可以推断出它的值没有被使用并且没有产生所需的副作用(包括由调用函数或访问易失性对象引起的任何副作用)。"
如果编译程序#3并禁用优化(-O0
)或依赖于编译器,仍然可以分配对象。在您的情况下,它不会显示在data
和rodata
部分,而是显示在text
部分,因此text
部分会增加。
例如,在您的第三个示例中,在我的编译器中,使用-O0
生成的代码(使用objdump -d
转储):
00000000004004d0 <main>:
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 <main>:
4004d0: 31 c0 xor %eax,%eax
4004d2: c3 retq
4004d3: 90 nop
并且该字符串未显示在data
或rodata
中,只是进行了优化。
答案 1 :(得分:2)
这是应该发生的事情:
代码1:任何地方都没有存储。
代码2:a
存储在堆栈中。它不存储在.data
。
代码3 a
要么存储在堆栈中,要么存储在.rodata
中,具体取决于它是否使用常量表达式进行初始化。优化器也可能决定将其存储在.text
中(与代码一起)。
我认为3个代码之间的数据段没有任何差异。
那是因为应该没有区别。 .data
用于静态存储持续时间的非常量变量,初始化为非零值。