extern
読み:エクスターン
外語:extern
C/C++の予約語の一つ。
特徴
C/C++
シンボルがファイルの外部で定義されていることを示す。
extern int hoge;
のように宣言しておくと、そのファイル内で変数があるかのように利用できる。但し、リンクする際に該当するものが見つからなかった場合はリンクエラーとなる。
C++
C++ではクラスが追加されたため、コンパイルして得られる関数や変数のシンボルがCと非互換となる。
そのままではCの関数をリンクすることが出来ないため、extern指定子が拡張された。
extern string-literal { declaration-listopt }
extern string-literal declaration
具体的には、次のように使う。
extern "C" int c_function(int num);
これにより、C++コンパイラーにCの関数であることを明示し、C++からCの関数を呼び出せるようになる。
string-literalは言語名を表わしている。C++11のドラフトでは "C" と "C++" が定義されており、それ以外の言語名は、その言語の仕様書から文字列を得るのが良いとしている。
通常は "C++" が使われることはないが、理論上は、extern "C" {} のCのコードの中でC++を使いたい場合などに使われうる。
拡張性が考慮されているため、extern "D" など実装依存の拡張も可能で、実際、IBM XL C++では、COBOLプログラムを呼び出すため extern "COBOL" が実装されているらしい。
C++11
C++11では、外部テンプレートの指定にも用いる。
C++の従来仕様では、その翻訳単位ごとにtemplateを実体化する仕様になっているが、これがコンパイル時間を伸ばす原因にもなっていた。C++の従来仕様で、強制的にtemplateを実体化する機能はあったが禁止する機能は無かったため、C++11ではこれを禁止するための機能が用意された。
従来C++でも対応する、templateの強制的な実体化の構文は次の通り。
template class std::vector<ClassName>;
C++11では、これにexternを付けることで実体化を抑止することとした。
extern template class std::vector<ClassName>;
この宣言をすることで、C++コンパイラーは、その翻訳範囲内で実体化をしないようになる。
再検索