関数内で外部変数を定義することが意味をなさない理由は次のとおりです。
シンボル extern を宣言すると、この値が出現するすべての箇所を同じシンボルにリンクするようコンパイラに指示することになります。extern int i; の出現。あなたのプログラムでは、外部で定義された i にリンクします。この例を見てください:
#include <iostream>
using namespace std;
extern int i;
int i = 10;
void test()
{
std::cout << "Hi" << i << std::endl;
}
int main()
{
extern int i;
i++;
test();
}
この例では、hi11 が出力されます。ただし、main 内の extern を削除すると、10 が出力されます。これは、extern がないと、i がグローバル i にリンクせず、i の独自のローカル コピーを作成するためです。
関数内で extern i を定義することが意味をなさない理由は、どの関数でも i を「定義」できるようにするとどうなるかということです。最初に実行される関数はどれですか? いつ定義されますか?
次の例が有効であると仮定すると、出力はどうなるでしょうか???
#include <iostream>
using namespace std;
extern int i;
int i = 10;
void test()
{
std::cout << "Hi" << i << std::endl;
}
void test2() {
extern int i = 1000;
std::cout<< "HI" << i << std::endl;
}
void test3() {
extern int i;
i = 1000;
std::cout<< "HI" << i << std::endl;
}
int main()
{
extern int i;
i++;
test();
i = 0;
test2();
}
test2 の出力は 0 か 1000 か? また、私の test3 を見てください。ここでは、私の i を外部で定義された i にリンクし、その値を 1000 として割り当てます。これは、値を「初期化」しようとすることとは大きく異なります。
要するに、extern 変数は実際にはグローバルとしてのみ意味があり、グローバル スコープで定義する必要があります。あなたの例では、最初のバージョンもコンパイルされません。これは面白いと思います。これが簡潔に定義されているかどうか、または追加の保護を追加するように設計された方法でコンパイラがこれを処理している可能性があるかどうかを確認するには、標準ドキュメントを調べる価値があるかもしれません...