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

Mah*_*ori 4 c memory gcc

我正在使用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 
Run Code Online (Sandbox Code Playgroud)

代码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 
Run Code Online (Sandbox Code Playgroud)

代码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
Run Code Online (Sandbox Code Playgroud)

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

在期待中感谢!

oua*_*uah 10

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

从C标准:

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

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

如果编译程序#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
Run Code Online (Sandbox Code Playgroud)

0x4f4c4c4548 是字符串的ASCII字符在寄存器中移动然后被压入堆栈中.

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

00000000004004d0 <main>:
  4004d0:       31 c0                   xor    %eax,%eax
  4004d2:       c3                      retq
  4004d3:       90                      nop
Run Code Online (Sandbox Code Playgroud)

并且字符串没有出现在datarodata,它只是优化了.

  • @EugenePodskal没有"hex"部分."dec"是基数为10的数据+文本+ bss,"hex"是相同的但是基数为16. (2认同)