Recently,I learned that the .bss
segment stores uninitialized data. However, when I try a small program as below and use size(1)
command in terminal, the .bss
segment didn't change, even if I add some global variables. Do I misunderstand something?
jameschu@aspire-e5-573g:~$ cat test.c
#include <stdio.h>
int main(void)
{
printf("hello world\n");
return 0;
}
jameschu@aspire-e5-573g:~$ gcc -c test.c
jameschu@aspire-e5-573g:~$ size test.o
text data bss dec hex filename
89 0 0 89 59 test.o
jameschu@aspire-e5-573g:~$ cat test.c
#include <stdio.h>
int a1;
int a2;
int a3;
int main(void)
{
printf("hello world\n");
return 0;
}
jameschu@aspire-e5-573g:~$ gcc -c test.c
jameschu@aspire-e5-573g:~$ size test.o
text data bss dec hex filename
89 0 0 89 59 test.o
This is because the way global variables work.
The problem that is being solved is that it is possible to declare a global variable, without initializing it, in several
.c
files and not getting a duplicate symbol error. That is, every global uninitialized declaration works like a weak declaration, that can be consideredexternal
if no other declaration contains an initialization.How it this implemented by the compiler? Easy:
bss
segment it will be added to theCOMMON
segment.COMMON
variables with the same name and discard anyone that is already in other section. The remaining ones will be moved to thebss
of the executable.And that is why you don't see your variables in the
bss
of the object file, but you do in the executable file.You can check the contents of the object sections using a more modern alternative to
size
, such asobjdump -x
. And note how the variables are placed in*COM*
.It is worth noting that if you declare your global variable as
static
you are saying that the variable belongs to that compilation unit, so theCOMMON
is not used and you get the behavior you expect:Initializing to
0
will get a similar result.However initializing to anything other than
0
will move that variable todata
: