我正在使用 GCC 4.8.1,它似乎没有在 DATA 段中存储 main 本地的 const 变量。下面是 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 个代码之间的数据段有任何差异。谁能给我解释一下这个结果。
感谢期待!
最佳答案
如果您的数组未被您的程序使用,那么允许编译器简单地优化对象。
来自 C 标准:
(C99, 5.1.2.3p1) "The semantic descriptions in this International Standard describe the behavior of an abstract machine in which issues of optimization are irrelevant"
和
(C99, 5.1.2.3p3) "In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object)."
如果您在禁用优化 (-O0
) 的情况下编译您的程序 #3,或者根据您的编译器,该对象仍然可以分配。在您的情况下,它不会出现在 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
中,它只是被优化掉了。
关于c - 对于 'C' 程序,常量局部变量数组在内存中的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24431015/