4

I am using GCC 4.8.1 and it doesn't seem to store const variable local to main in DATA segment. Below is code and memory map for 3 such programs:

Code 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 

CODE 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 

CODE 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

I do not see any difference in data segment between 3 codes. Can someone please explain this result to me.

Thanks in anticipation!

mahoriR
  • 4,377
  • 3
  • 18
  • 27

2 Answers2

11

If your array is not used by your program so the compiler is allowed to simply optimize out the object.

From the C Standard:

(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"

and

(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)."

If you compile your program #3 with optimizations disabled (-O0) or depending on your compiler the object can still be allocated. In your case it does not appear in the data and rodata section but in text section thus the text section increase.

For example in your third example, in my compiler the resulting code with -O0 is (dumped using 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 is the ASCII characters of your string moved in a register and then pushed in the stack.

If I compile the same program with -O3, the output is simply:

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

and the string does not appear in data or rodata, it is simply optimized out.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • 1
    But why is the hex section's size differ? – Eugene Podskal Jun 26 '14 at 12:55
  • I see the same result after turning compiler optimization as well. To turn optimizations off, I am using C:/> gcc -O0 code.c – mahoriR Jun 26 '14 at 13:02
  • @EugenePodskal depending on the `-On` optimization used the array may be not optimized out but small arrays may not go on data or rodata section but directly in text with array elements being explicitly pushed to the stack. – ouah Jun 26 '14 at 13:02
  • 3
    @EugenePodskal There is no "hex" section. "dec" is data+text+bss in base 10, "hex" is the same but base 16. – Art Jun 26 '14 at 13:40
  • I thought that "hex" is some sort of an alias for another section. Thank you for pointing it out. – Eugene Podskal Jun 26 '14 at 13:44
4

This is what should happen:

Code 1: nothing is stored anywhere.

Code 2: a is stored on the stack. It is not stored in .data.

Code 3 a is either stored on the stack or in .rodata, depending on whether it is initialized with a constant expression or not. The optimizer might also decide to store it in .text (together with the code).

I do not see any difference in data segment between 3 codes.

That's because there should be no difference. .data is used for non-constant variables with static storage duration that are initialized to a value other than zero.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • Related question: http://stackoverflow.com/questions/12798486/bss-segment-in-c/12799389#12799389 – Lundin Jun 26 '14 at 13:21
  • I read an answer said the data segment contains `.rodata` and uninitialized data, while you said they're initialized, so which is correct? https://stackoverflow.com/a/14588938/5290519 – NeoZoom.lua Feb 20 '21 at 05:19
  • @Rainning `.data` contains initialized read/write variables. `.rodata` contains initializers and other constands. And when that answer speaks of uninitialized data in `.bss`, it actually mean zero-initialized. All variables with static storage duration that are uninitialized by the programmer, gets initialized to zero and end up in `.bss`. Same thing with variables that are explicitly initialized to zero. – Lundin Feb 22 '21 at 07:56