30

All the initialized global/static variables will go to initialized data section. All the uninitialized global/static variables will go to uninitialed data section(BSS). The variables in BSS will get a value 0 during program load time.

If a global variable is explicitly initialized to zero (int myglobal = 0), where that variable will be stored?

Lunar Mushrooms
  • 8,358
  • 18
  • 66
  • 88
  • 5
    What happens when you try it? You can see what's in a `.o` file using `objdump -x`. – Greg Hewgill Jan 04 '12 at 02:54
  • I tried below A).for int globalvar = 0 ; objdump -x test > 1.txt B).for ==> int globalvar; objdump -x test > 2.txt And the diff is: - 2 .bss 00000004 00000000 00000000 00000058 2**2 + 2 .bss 00000000 00000000 00000000 00000058 2**2 -00000000 g O .bss 00000004 globalvar +00000004 O *COM* 00000004 globalvar – Lunar Mushrooms Jan 04 '12 at 03:07
  • @LunarMushrooms Update post *ahem* :) –  Jan 04 '12 at 03:30

3 Answers3

35

Compiler is free to put such variable into bss as well as into data. For example, GCC has a special option controlling such behavior:

-fno-zero-initialized-in-bss

If the target supports a BSS section, GCC by default puts variables that are initialized to zero into BSS. This can save space in the resulting code. This option turns off this behavior because some programs explicitly rely on variables going to the data section. E.g., so that the resulting executable can find the beginning of that section and/or make assumptions based on that.

The default is -fzero-initialized-in-bss.

Tried with the following example (test.c file):

int put_me_somewhere = 0;

int main(int argc, char* argv[]) { return 0; }

Compiling with no options (implicitly -fzero-initialized-in-bss):

$ touch test.c && make test && objdump -x test | grep put_me_somewhere
cc     test.c   -o test
0000000000601028 g     O .bss   0000000000000004              put_me_somewhere

Compiling with -fno-zero-initialized-in-bss option:

$ touch test.c && make test CFLAGS=-fno-zero-initialized-in-bss && objdump -x test | grep put_me_somewhere
cc -fno-zero-initialized-in-bss    test.c   -o test
0000000000601018 g     O .data  0000000000000004              put_me_somewhere
Eldar Abusalimov
  • 24,387
  • 4
  • 67
  • 71
6

It's easy enough to test for a specific compiler:

$ cat bss.c
int global_no_value;
int global_initialized = 0;

int main(int argc, char* argv[]) {
    return 0;
}
$ make bss
cc     bss.c   -o bss
$ readelf -s bss | grep global_
    32: 0000000000400420     0 FUNC    LOCAL  DEFAULT   13 __do_global_dtors_aux
    40: 0000000000400570     0 FUNC    LOCAL  DEFAULT   13 __do_global_ctors_aux
    55: 0000000000601028     4 OBJECT  GLOBAL DEFAULT   25 global_initialized
    60: 000000000060102c     4 OBJECT  GLOBAL DEFAULT   25 global_no_value

We're looking for the location of 0000000000601028 and 000000000060102c:

$ readelf -S bss
There are 30 section headers, starting at offset 0x1170:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
...
  [24] .data             PROGBITS         0000000000601008  00001008
       0000000000000010  0000000000000000  WA       0     0     8
  [25] .bss              NOBITS           0000000000601018  00001018
       0000000000000018  0000000000000000  WA       0     0     8

It looks like both values are stored in the .bss section on my system: gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4).

sarnold
  • 102,305
  • 22
  • 181
  • 238
2

The behavior is dependent upon the C implementation. It may end up in either .data or .bss, and to increase changes that it does not end up in .data taking redundant space up, it's better not to explicitly initialize it to 0, since it will be set to 0 anyway if the object is of static duration.

jørgensen
  • 10,149
  • 2
  • 20
  • 27
  • This question is tagged GCC (although the version/target is not specified). –  Jan 04 '12 at 03:31