commonって何だ? nm 謎解き編

[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ cat comm1.c
#include <stdio.h>

int ver_major, ver_minor;

int main(void) {
 printf("Version is %d %d\n", ver_major , ver_minor);
 return 0;
}

[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ cat comm2.c 
int ver_major = 2 , ver_minor = 4;

[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ 


個別にコンパイルして、nm -gをみていると

[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ cat comm1.c
#include <stdio.h>

int ver_major, ver_minor;

int main(void) {
 printf("Version is %d %d\n", ver_major , ver_minor);
 return 0;
}
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ cat comm2.c 
int ver_major = 2 , ver_minor = 4;

[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ 
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ 
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ gcc -Wall -save-temps -o comm1 comm1.c
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ 
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ 
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ nm -g comm1.o
00000000 T main
         U printf
00000004 C ver_major
00000004 C ver_minor
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ gcc -Wall -save-temps -o comm2 comm2.c 
/usr/lib/gcc/i486-linux-gnu/4.4.3/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ gcc -Wall -save-temps -c comm2.c 
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ 
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ nm -g comm2.o
00000000 D ver_major
00000004 D ver_minor
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ gcc -o common comm1.o comm2.o
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ 
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ nm -g common 
080484dc R _IO_stdin_used
         w _Jv_RegisterClasses
08049f18 D __DTOR_END__
0804a01c A __bss_start
0804a00c D __data_start
0804a010 D __dso_handle
         w __gmon_start__
0804848a T __i686.get_pc_thunk.bx
08048420 T __libc_csu_fini
08048430 T __libc_csu_init
         U __libc_start_main@@GLIBC_2.0
0804a01c A _edata
0804a024 A _end
080484bc T _fini
080484d8 R _fp_hw
080482bc T _init
08048330 T _start
0804a00c W data_start
080483e4 T main
         U printf@@GLIBC_2.0
0804a014 D ver_major
0804a018 D ver_minor
[hirasawa@ubunt1004-32-2 gcc-Programming-Kobo]$ 


gccでは、秘書帰化変数はデフォでcommonセクションに
配置される
commonセクション内では、一つのシンボルを重複して定義することが
許されている。

もしも当該シンボルが、どのファイルにおいても初期化されなければ、
.bss
逆にどこかで初期化されれば、.dataに置かれる。


厳密にいえば、これは"重複定義エラー"で、
comm1.cの部分は extern int ver_major, ver_minorとすべき。

Cではグローバル変数が増えてくると、それぞれのていぎを厳密に
管理するのが困難であるための甘やかし、だそうです。

 gccには -fno-commonオプションなる厳密なオプションあり