Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where does constant local variable array go in memory for a 'C' program

Tags:

c

memory

gcc

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!

like image 833
mahoriR Avatar asked Dec 12 '22 05:12

mahoriR


2 Answers

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.

like image 156
ouah Avatar answered May 04 '23 01:05

ouah


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.

like image 31
Lundin Avatar answered May 04 '23 01:05

Lundin