【C++ベースの7】externキーワード


1.作用
(1)関数または変数の前に置いて、変数または関数の定義を別のファイルに表示し、コンパイラがこの変数と関数に遭遇したときに他のモジュールで定義を探すようにプロンプトします.
(2)「C」と連用し、接続として指定する.
2.具体的な説明及び例
2.1.externの変数と関数宣言
externは変数または関数を修飾するために使用され、現在の変数または関数が本モジュールまたは他のモジュールで使用できることを宣言するために使用されます.しかし、externは定義ではなく宣言にすぎないことを覚えておいてください.つまり、externは空間を割り当てません.この検索は接続中に行われるため、コンパイルフェーズでは変数や関数が見つからないが、エラーは報告されません.次は3つの例で見てみましょう.
(1)extern宣言なし、変数定義あり.
stdafx.cpp
#include "stdafx.h"
int g_test;
main.cpp
int _tmain(int argc, _TCHAR* argv[])
{
	g_test=2;
	std::cout<<g_test;
	return 0;
}

mainでg_を呼び出すことができないため、エラーが表示されます.test.
1>d:\microsoft visual studio 9.0\projects\testcpp\testcpp\testcpp.cpp(25):error C 2065:"g_test":宣言されていない識別子1>d:microsoft visual studio 9.0projectstestcpptestcpptestcpp.cpp(26):error C 2065:「g_test」:宣言されていない識別子
(2)extern宣言あり、変数定義なし.
stdafx.h
extern int g_test;
main.cpp
int _tmain(int argc, _TCHAR* argv[])
{
	g_test=2;
	std::cout<<g_test;
	return 0;
}

ヒントエラー、externは宣言だけなので、定義も空間の割り当てもありませんが、このときリンクエラーは、コンパイル時に発見できません.
1>TestCpp.OBj:error LNK 2001:解析不能外部符号「int g_test」(?g_test@@3 HA)1>D:Microsoft Visual Studio 9.0ProjectsTestCppDebugTestCpp.Exce:fatal error LNK 1120:1個の解析不能外部コマンド
(3)extern宣言があり,変数定義もある.
stdafx.cpp
#include "stdafx.h"
int g_test;

stdafx.h
extern int g_test;

main.cpp
int _tmain(int argc, _TCHAR* argv[])
{
	g_test=2;
	std::cout<<g_test;
	return 0;
}

プログラムは正常に実行されます.
2.2.extern "C"
これは覇気が表に出るものですね.はい、歴史は問題を残しています.最初の標準Cコンパイラのコンパイルで引用された変数と関数は、void foo(int a,int b)のような名前の前にスランプを付けることです.コンパイラが参照する関数名は_foo、その後のCコンパイラはこの基準に従っています.
しかし、その後、C++が現れ、彼のリロード特性は異なるコンパイラにvoid foo(int a,int b)などの異なる処理をさせた.コンパイラに引用されて_になる可能性があります.foo_int_intなど、関数名にも関数パラメータを入れてリロードを実現します.異なるメーカーが生産したモジュール間の互換性を保証し、開発したCモジュールを呼び出すことができるように、extern「C」の方法を引き出し、この定義を通じてコンパイラに、Cの方法で私のこの関数をコンパイルして、私の名前を維持してくださいと伝えました.このように異なるメーカーのCとC++の変数,関数,クラスは一貫化された処理が得られ,互換性も解決される.
これは標準的なextern「C」の書き方です.これはdllの作成に大きな役割を果たします.
// .h     
#ifdef __cplusplus
#if __cplusplus
extern "C"{
 #endif
 #endif /* __cplusplus */ 
 …
 …
 //.h       
 #ifdef __cplusplus
 #if __cplusplus
}
#endif
#endif /* __cplusplus */