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オプションなる厳密なオプションあり