28

例えば:

code1.c / .cpp

int a;

// ... and so on

code2.c / .cpp

int a;

int main(void) {
    return 0;
}

コンパイルに行きます:

$gcc code1.c code2.c      # this is fine
$

$g++ code1.cpp code2.cpp  # this is dead
/tmp/ccLY66HQ.o:(.bss+0x0): multiple definition of `a'
/tmp/ccnIOmPC.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status

CとC++の間にグローバル変数リンケージの違いはありますか?

4

4 に答える 4

21

厳密には合法ではありません。int a;は C の暫定定義です。C の外部リンケージを持つ各オブジェクトの翻訳単位ごとに、複数の暫定定義と最大 1 つの非暫定定義が許可されますが、プログラム内のすべての翻訳単位で 1 つの定義のみが許可されます。

複数の翻訳単位に非仮定義が含まれていない限り、C の複数の翻訳単位にまたがる仮定義を許可する拡張機能が一般的に実装されていますが、これは厳密には標準ではありません。

C++ ではint a;単なる定義であり、仮の概念はありません。また、プログラムの翻訳単位全体でオブジェクトの複数の定義を持つことは依然として違法です。

C のケースについては、この質問を参照してください。

于 2011-06-16T11:35:59.743 に答える
4

どちらも違法ですが、C コンパイラは一般に拡張機能を実装しています。この回答を参照してください。

于 2011-06-16T11:35:13.137 に答える
2

問題を解決するには、次の 3 つの方法があります。

  1. variableが両方のファイルで同じである場合は、 1 つを除くすべてのファイルaで同じように宣言する必要があります。キーワードは、この名前が別のファイルにあることをリンカーに伝えます。externextern

  2. キーワードを使用staticして、変数のスコープを 1 つのファイルに制限できます。それが宣言されています。

  3. または、名前のない名前空間を使用することもできます。

于 2011-06-16T11:38:14.190 に答える
1

g++ コンパイラは gcc コンパイラよりも厳密です。また、gcc のバージョンにも依存します。gcc の上位バージョン、つまり 4.X 以降でも同じエラーが発生する可能性があります。

extern避けるために使う

于 2011-06-16T11:40:47.753 に答える