2017-11-11 9 views
6

C++では、参照変数を初期化する必要があります。 int&a; //エラーなぜ "extern int&c;"ですか?うまく動作しますか?

static int &b; // Error 

しかし

extern int &c; // No error 

なぜコンパイラはextern指定子参考のためにエラーを与えるものではありませんか?

+2

外部定義で初期化が強制されるためです。 – user0042

+3

'extern'ビットは' c'がどこか他の場所で宣言され/定義されていることをコンパイラに伝えます。 –

+4

@rsp extern int&c;参照の定義ではありません。それは定義のない宣言に過ぎません。 –

答えて

12

キーワードは、別のオブジェクトファイルから取得したリンク時に記入されるシンボルを宣言するコンパイラ用のディレクティブです。 初期化は、実際のシンボルが定義されているところで起こると予想されます。

あなたはコンパイラが空barのシンボルを残してb.oにファイルb.cをコンパイルするときは、

int foo; 
int &bar = foo; 

とa.cファイルと

extern int &bar; 

とb.cファイルを持っている場合。プログラムをリンクする際、リンカはAOでエクスポートシンボルbarを見つける必要がありますし、リンカが必要なシンボルを見つけることができない場合は、リンクされたオブジェクト内のどこにでもAO

からbarとboの空白記号に置き換えられますファイル - リンカーエラー(コンパイラーエラーではない)が発行されます。

5

なぜコンパイラはexternの参照でエラーを起こさないのですか?

extern int &c;は、定義、単に宣言ではありませんので。 cがプログラムのどこか他で定義されることをコンパイラに知らせています。

cppreference page on "storage class specifiers"は、このシナリオでexternの意味を説明しています。

5

言語仕様は明示的に述べてい

8.3.2参照
[...]宣言が含まれている場合を除き、初期化子(8.6.3)を含まなければならない参照の宣言明示的なextern指定子(7.1.1)、クラス定義内のクラスメンバ(9.2)宣言、または のパラメータまたは戻り値の型(8.3.5)の宣言です。 3.1を参照してください。

お客様の状況は直接この見積もりの​​対象となります。つまり、一般的な宣言定義ルールからの参照は除外されません。他の場所で定義された(そして初期化された)参照のための非定義宣言を作成することができます。

明示的なexternキーワードを持つリファレンス宣言にイニシャライザを組み込むことは禁止されています。しかし、通常どおり、定義されていない宣言をの定義に変換します。

関連する問題