c&c ++のデフォルトのグローバル変数リンケージ、複数の宣言と定義の問題
-
28-10-2019 - |
質問
例:
code1.c / .cpp ジェネラコディセタグプレ
code2.c / .cpp ジェネラコディセタグプレ
コンパイルに移動: ジェネラコディセタグプレ
CとC ++の間にグローバル変数リンケージの違いはありますか?
解決
厳密には合法ではありません。int a;
は、Cの暫定的な定義です。複数の暫定的な定義と、Cの外部リンケージを持つ各オブジェクトの翻訳単位ごとに最大で1つの非暫定的な定義が許可されますが、プログラム内のすべての翻訳単位で1つの定義のみが許可されます。
これは一般的に実装されている拡張機能であり、Cの複数の翻訳ユニットにまたがる暫定的な定義を許可します。ただし、非暫定的な定義が含まれる翻訳ユニットは1つだけですが、厳密には標準ではありません。
C ++では、int a;
は単なる定義であり、暫定的な概念はありません。プログラムの翻訳単位全体にオブジェクトの複数の定義を含めることは依然として違法です。
Cの場合は、この質問。
他のヒント
どちらも違法ですが、Cコンパイラは一般的に拡張機能を実装しています。
問題を解決するには3つの方法があります:
-
変数
a
が両方のファイルで同じである場合、1つを除くすべてのファイルでextern
として宣言する必要があります。extern
キーワードは、この名前が別のファイルにあることをリンカーに伝えます。 -
static
キーワードを使用して、変数のスコープを1つのファイルに制限できます。宣言されている場所。 -
または、名前のない名前空間を使用することもできます。
g ++コンパイラは、gccコンパイラよりも厳密です。 また、gccのバージョンによっても異なりますが、gccの上位バージョン、つまり4.X以降でも同じエラーが発生する可能性があります。
回避するにはextern
を使用してください