Reputation: 115
To the best of my understanding, static variables that are not explicitely initialized (and, with GCC, even those that are explicitely initialized to zero if -fzero-initialized-in-bss
is set, which is the case by default) are usually stored in the BSS segment. Yet, it seems that when I try to inspect that behaviour, those variables are stored in the general data section (with initialized globals). If I compile (with -O0
for good measure) and run:
#include <stdio.h>
#include <stdlib.h>
extern char etext, edata, end;
int i = 42;
int main(int argc, char* argv[])
{
static int j;
printf ("end of program (etext) = %10p\n",&etext);
printf ("end of initialized data (edata) = %10p\n",&end);
printf ("end of uninitialized data (end) = %10p\n",&end);
printf ("=====\n");
printf ("Value of i (initialized global) : %d\n",i);
printf ("Address of i : %10p\n",&i);
printf ("Value of j (static with no explicit initialization) : %d\n",j);
printf ("Address of i : %10p\n",&j);
return 0;
}
I get the output:
end of program (etext) = 0x40067d
end of initialized data (edata) = 0x600af0
end of uninitialized data (end) = 0x600af0
=====
Value of i (initialized global) : 42
Address of i : 0x600ae0
Value of j (static with no explicit initialization) : 0
Address of i : 0x600ae8
So i
and j
are stored at contiguous memory address, between &etext
and &edata
, which is the regular data section. Furthermore, it seems that &edata == &end
which, if I understand correctly, would mean that the BSS is empty.
Now I realize that where the compiler puts which variable is an implementation choice and the results it produces is correct. But I am just wondering why I get that behaviour, and if there is a way to tell gcc to explicitely put such variables in the BSS (I didn't see any obvious solution in the manual).
Upvotes: 3
Views: 823
Reputation: 25286
The BSS in the executable image is just a number that says how many bytes to reserve upon load for the uninitialized variables. In this way the image doesn't get unwieldly large for many of these uninitialized variables. When the number is very small, such as in your example, there is hardly any saving and only overhead and the compiler may have decided to place them all in the DATA segment.
Upvotes: 3
Reputation: 31193
You have an error in your code. You print the address of end
for both edata and end, so of course you assume edata == end, which they are not.
When I fixed your code and run it I get:
end of program (etext) = 0x8048578
end of initialized data (edata) = 0x804988c
end of uninitialized data (end) = 0x8049894Value of i (initialized global) : 42
Address of i : 0x8049888
Value of j (static with no explicit initialization) : 0
Address of j : 0x8049890
So clearly j
is in the area between edata and end and not in the same place as i
.
(gcc 5.2.1 20150911 (Debian 5.2.1-17), 32bit)
Upvotes: 4