2

私は extern に基づいたプログラムを試していましたが、私が理解しているように、これは定義が 1 つしかない複数のファイルにまたがる変数にアクセスするときに役立ちます。

しかし、私は以下のような単純なプログラムを試してみましたexternが、リンクプロセス中に失敗すると予想していたときにうまくいくようです

file5.c:

#include <stdio.h>
#include "var.h"

int a = 20;

int main() {
  printf("\n File5.c a = %d", a);
  test();
  return 0;
}

file6.c:

#include <stdio.h>
#include "var.h"

int test() {
  printf("\n File6.c a = %d",a);
}

var.h

int a;

var.hextern なしですべてのヘッダー ファイルにインクルードint aしたため、ファイルとリンクの両方にインクルードされるため.c、コンパイラは警告またはエラー メッセージをスローする必要がありましたが、問題なくファイルをコンパイルします。

var.h次のようなものがあってはいけませんextern int aか?

4

1 に答える 1

2

一般に、ヘッダーで を使用するのが最適ですextern int a;C のソース ファイル間で変数を共有するにはどうすればよいですか?も参照してください。

標準は次のように述べています。

ISO/IEC 9899:2011 §6.9.2 外部オブジェクト定義

セマンティクス
¶1 オブジェクトの識別子の宣言にファイル スコープと初期化子がある場合、宣言は識別子の外部定義です。

¶2 初期化子なしのファイルスコープを持つオブジェクトの識別子の宣言で、ストレージクラス指定子がない場合、またはストレージクラス指定子がある場合は、仮の定義staticを構成し ます。翻訳単位に識別子の暫定的な定義が 1 つ以上含まれており、翻訳単位にその識別子の外部定義が含まれていない場合、動作は、翻訳単位にその識別子のファイル スコープ宣言が含まれているかのように、複合型は次のようになります。 0 に等しい初期化子を使用して、翻訳単位の末尾を指定します。

したがって、ヘッダーにあるのは、変数の暫定的な定義です。の翻訳単位 (TU) の最後ではfile5.c、暫定的な定義はありません。によって指定された「外部定義」はそれを指定しint a = 20;ています。の TU の最後には、file6.cと同等の定義がありますint a = 0;

と をリンクしようとするfile5.cfile6.c、 の複数の定義に遭遇するはずですa。ただし、付属書 J の標準に文書化されている一般的な拡張機能があります。

J.5.11 複数の外部定義

¶1 オブジェクトの識別子には、キーワード の明示的な使用の有無にかかわらず、複数の外部定義が存在する場合がありますextern。定義が一致しない場合、または複数が初期化されている場合、動作は未定義です (6.9.2)。

あなたのコンパイラは、§J.5.11 で特定された拡張機能を提供しているため、(正当に) 文句を言いません。

580

于 2013-09-07T20:13:43.823 に答える