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

时间:2014-06-26 12:50:20

标签: c gcc memory

我正在使用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个代码之间的数据段没有任何差异。有人可以向我解释这个结果。

感谢您的期待!

2 个答案:

答案 0 :(得分:10)

如果你的程序没有使用你的数组,那么允许编译器简单地优化对象。

来自C标准:

  

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

  

(C99,5.1.2.3p3)"在抽象机器中,所有表达式都按语义指定进行计算。实际实现不需要评估表达式的一部分,如果它可以推断出它的值没有被使用并且没有产生所需的副作用(包括由调用函数或访问易失性对象引起的任何副作用)。"

如果编译程序#3并禁用优化(-O0)或依赖于编译器,仍然可以分配对象。在您的情况下,它不会显示在datarodata部分,而是显示在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

并且该字符串未显示在datarodata中,只是进行了优化。

答案 1 :(得分:2)

这是应该发生的事情:

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

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

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

  

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

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