ヘッダファイル内のグローバル変数

私は2つのモジュール(.cファイル)と1つの.hヘッダファイルを持っています:

file1.c:

#include 
#include "global.h"

int main()
{
    i = 100;
    printf("%dn",i);
    foo();
    return 0;
}

file2.c

#include 
#include "global.h"

void foo()
{
    i = 10;
    printf("%dn",i);
}

global.h

int i;
extern void foo()

gcc file1.c
file2.cを実行するとすべて正常に動作し、期待される出力が得られます。今、私は0と言うようにヘッダーファイル内の変数
‘i’を初期化し、再度コンパイルするとリンカーエラーが発生します:

/tmp/cc0oj7yA.o:(.bss+0x0): multiple definition of `i'
/tmp/cckd7TTI.o:(.bss+0x0): first defined here

ヘッダーファイル(gcc
file1.c)の初期化でfile1.c(foo()への呼び出しを削除する)をコンパイルするだけで、すべて正常に動作します。何が起こっている?

ベストアンサー

以下の3つのシナリオがあります。

    2つの .c ファイルと int i;2つの
    .c ファイルと int i = 100; のヘッダー(またはそれ以外の値) 1
    .c ファイルと int i = 100;

それぞれのシナリオで、ヘッダファイルの内容を .c ファイルと .o
ファイルにコンパイルしたこの .c これらは一緒につながっています。

次に、

    すべての .o ファイルにはそのうちの1つが含まれているので、リンカーは「ok」と言います。両方の
    .o ファイルには(たとえ値が同じであっても)衝突する値を持つ定義が含まれているため、

  1. は機能しません。 .o ファイル内のすべてのファイル名を指定します。

  2. .o ファイルが1つしかなく、衝突の可能性がないので、もちろん動作します。

きれいなことがIMHOになる

  • ヘッダーファイルに extern int i; または int
    i;
  • 次に、 file1.c にiの “実際の”定義(つまり int i =
    100;
    )を置きます。この場合、この初期化はプログラムの開始時に使用され、
    main()の対応する行は省略できます。
    (また、命名は単なる例であり、実際のプログラムではグローバル変数の名前を i
    にしないでください)。

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です