私は2つのプロジェクトを作成しました。最初のプロジェクトはCで、2番目のプロジェクトはC++で、どちらも同じ動作をします。
Cプロジェクト:
header.h
int varGlobal=7;
main.c
#include <stdio.h>
#include <stdlib.h>
#include "header.h"
void function(int i)
{
static int a=0;
a++;
int t=i;
i=varGlobal;
varGlobal=t;
printf("Call #%d:\ni=%d\nvarGlobal=%d\n\n",a,i,varGlobal,t);
}
int main() {
function(4);
function(6);
function(12);
return 0;
}
C++プロジェクト:
header.h
int varGlobal=7;
main.cpp
#include <iostream>
#include "header.h"
using namespace std;
void function(int i)
{
static int a=0;
int t=i;
a++;
i=varGlobal;
varGlobal=t;
cout<<"Call #"<<a<<":"<<endl<<"i="<<i<<endl<<"varGlobal="<<varGlobal<<endl<<endl;
}
int main() {
function(4);
function(6);
function(12);
return 0;
}
グローバル変数は、デフォルトではCでexternであり、C++ではデフォルトでstaticであると読みました。では、なぜC++コードが機能するのでしょうか?
つまり、int varGlobal = 7;はstatic int varGlobal = 7;と同じで、静的な場合にのみ使用できますファイル内で宣言されましたよね?
グローバル変数は、CおよびC++ではデフォルトでextern
でもstatic
でもありません。変数をstatic
として宣言すると、現在のソースファイルに制限されます。 extern
として宣言すると、変数は存在するが別の場所で宣言されていると言っており、他の場所で(extern
キーワードなしで)宣言していない場合は、リンクエラー(シンボルが見つかりません)。
そのヘッダーを含むソースファイルがさらにあると、コードは壊れます。リンク時に、varGlobal
への複数の参照があります。 static
として宣言すると、複数のソースで動作します(つまり、コンパイルしてリンクします)が、各ソースには独自のvarGlobal
があります。
Cではできない、C++でできることは、次のようにヘッダーで変数をconst
として宣言することです。
const int varGlobal = 7;
リンク時に物事を壊すことなく、複数のソースに含めます。考え方は、古いCスタイル#define
定数用。
const
ではなく複数のソースで表示できるグローバル変数が必要な場合は、ヘッダーでextern
として宣言し、今回はソースファイルでexternキーワークなしで再度宣言します。
複数のファイルに含まれるヘッダー:
extern int varGlobal;
ソースファイルのいずれか:
int varGlobal = 7;
#include
ヘッダー。ソースファイル自体にコードを挿入した場合とまったく同じです。どちらの場合も、varGlobal
変数はソースで定義されているため、どのように宣言されていても機能します。
また、コメントで指摘されているように、ファイルスコープのC++変数は、静的ストレージに割り当てられますが、スコープ内で静的ではありません。たとえば、変数がクラスメンバである場合、デフォルトでプログラム内の他のコンパイルユニットにアクセスできる必要があり、非クラスメンバも同じです。