広域変数が配置されるセクション
※この実験は、以下の環境で実施しました。
$ gcc -v gcc バージョン 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1) $ as -V GNU アセンブラ バージョン 2.23.2 (i686-linux-gnu)、BFD バージョン (GNU Binutils for Ubuntu) 2.23.2 を使用 $ ld -v GNU ld (GNU Binutils for Ubuntu) 2.23.2
以下で場合分けをした広域変数を定義します。
1.初期値あり/なし 2.初期値=0またはNULL/0以外またはNULL以外 3.1と2について、const指定あり/なし
int n_void; int n_zero = 0; int n_notzero = 1; char *p_void; char *p_null = NULL; char *p_notnull = "This is pointer."; const int cn_void; const int cn_zero = 0; const int cn_notzero = 1; char * const cp_void; char * const cp_null = NULL; char * const cp_notnull = "This is pointer.";
上記のプログラムについて、シンボルテーブルをダンプすると、
$ nm pointer (中略) 080484a8 R cn_notzero 0804a038 B cn_void 080484a4 R cn_zero (中略) 080484b0 R cp_notnull 080484ac R cp_null 0804a03c B cp_void (中略) 0804a01c D n_notzero 0804a030 B n_void 0804a028 B n_zero 0804a020 D p_notnull 0804a02c B p_null 0804a034 B p_void
まとめると、以下となりました。
初期値 | const指定 | 配置先セクション |
---|---|---|
なし | なし | .bss |
なし | const | .bss |
0 or NULL | なし | .bss |
0 or NULL | const | .rodata |
上記以外 | なし | .data |
上記以外 | const | .rodata |
つまり、以下の評価順で、配置先セクションが決定される…ということのようです。
評価順 | 条件 | 配置先セクション |
---|---|---|
1 | 初期値なし | .bss |
2 | const指定あり | .rodata |
3 | 初期値=0またはNULL | .bss |
4 | 初期値が上記以外 | .data |
ヒューリスティック(大雑把)に表現すると、
・初期値の無い変数は、.bssセクションに配置される。 ・初期値の無いconst指定は無視される。 ・初期値のあるconst定数は、初期値の内容とは無関係に、.rodataセクションに配置される。 ・初期値のある変数は、 初期値=0またはNULL →初期値なしと同じ扱い。 上記以外 →.dataセクションに配置される。