5

実行可能ファイルの「共通」セクションについてもっと理解しようとしていますがobjdump、コンパイルされたコードで実行すると、実行可能ファイルではなくオブジェクトファイル()にのみ共通コードに配置された変数が表示されることに気付きまし*.oた。

何故ですか?

//test.c

int i[1000];
int main(){return 0;}

ビルドコマンド:

> gcc -g0 -fcommon -c test.c
> gcc -g0 -fcommon test.c

objdumpiシンボルテーブルの共通セクションに表示されます。

> objdump -x test.o
  ...
  SYMBOL TABLE:
  ...
  00000fa0    O   *COM*   00000020  i

実行可能ファイルで実行しない限り、次のようになります。

> objdump -x a.out
  ...
  SYMBOL TABLE:
  ...
  0804a040 g  O   .bss    00000fa0  i

-fno-common代わりにフラグを使用してオブジェクトファイルを再構築すると.bss、実行可能ファイルの場合と同じようにセグメントに表示されます。最終的な実行可能ファイルには、この「COMMON」セクションがありませんか?

4

1 に答える 1

6

共通セクションは、リンカーが知っているものです。基本的に、すべてのcommonコンテンツを[典型的な]実行可能ファイルが持つ3つまたは4つの実際のセクションの1つに入れます(コードまたはテキスト、データ、bss-場合によってはrodataもあります)。

したがって、この場合、変数は初期化されていないため、.bssになります。

-fcommon/のgccマニュアルから-fno-common

Cコードでは、初期化されていないグローバル変数の配置を制御します。Unix Cコンパイラは、従来、変数を共通のブロックに配置することにより、さまざまなコンパイル単位でそのような変数の複数の定義を許可してきました。これは-fcommonで指定された動作であり、ほとんどのターゲットでのGCCのデフォルトです。一方、この動作はISO Cでは必須ではなく、一部のターゲットでは、変数参照で速度またはコードサイズのペナルティが発生する可能性があります。-fno-commonオプションは、コンパイラが初期化されていないグローバル変数を共通ブロックとして生成するのではなく、オブジェクトファイルのデータセクションに配置する必要があることを指定します。これには、2つの異なるコンパイルで同じ変数が(externなしで)宣言されている場合、それらをリンクするときに複数定義エラーが発生するという効果があります。この場合、代わりに-fcommonを使用してコンパイルする必要があります。-fno-commonを使用したコンパイルは、パフォーマンスが向上するターゲットで、またはプログラムが初期化されていない変数宣言を常にこのように処理する他のシステムで動作することを確認する場合に役立ちます。

したがって、またはは、 [と呼ばれるグローバル変数が複数ある場合にのみ違いがあり-fno-commonます。同じサイズである必要があります。そうしないと、プログラムが無効になり、未定義の動作よりも1グレード悪くなります!]-fcommoni

于 2013-02-12T19:28:35.500 に答える