1

extern 指定子の次の使用例はどのように動作しますか。

ファイル one.c と two.c の両方にグローバル変数 int x があります。これらを three.c で使用したいので、この変数を three.c で次のように宣言しました。

extern int x;

これらのファイルをコンパイルしてリンクするとどうなるでしょうか?

私の答えは次のとおりです。これらすべてのファイルのコンパイルは成功するはずですが、x が複数宣言されているため、リンカはリンク時にエラーにフラグを立てる必要があります。C++ での動作に違いはありますか?

C と C++ の両方のファイルから int x (three.c 内) を同時に参照する方法はありますか。C++ では、名前空間を使用してこれを実現できると思います。右?

4

5 に答える 5

6

デフォルトでは、グローバル変数には外部リンケージがあります。これは、他のソースファイル(または「変換ユニット」)で使用できることを意味します。static代わりに、キーワードを使用してグローバル変数を宣言すると、それらは内部リンケージを持ちます。つまり、他のソースファイルでは使用できなくなります。

外部リンケージを持つ変数の場合、同じ名前の変数を複数持つことはできません。そうしないと、リンカが文句を言います。ただし、少なくとも1つに内部リンクがある限り、同じ名前の2つの変数を持つことができます。もちろん、同じソースファイルで両方を参照することはできません。

extern宣言は、コンパイラに「別の変換ユニットで定義された外部リンケージを持つ変数の名前です」と言っているだけで、その変数を参照できます。

名前空間が追加されていることを除けば、C++はまったく同じです。グローバル変数が名前空間内に配置されている場合、それらが異なる名前空間にある場合、リンカーエラーなしで同じ名前を持つことができます。もちろん、これらの変数へのすべての参照は、フルネームを参照するかnamespace::var_name、宣言を使用しusingてローカル名前空間コンテキストを確立する必要があります。

C ++には匿名の名前空間もあります。これはstatic、Cでグローバル変数にキーワードを使用するのとまったく同じです。匿名の名前空間内で宣言されたすべての変数と関数には内部リンクがあります。

したがって、元の質問に答えるのは正しいです。コンパイルは成功しますがx、外部リンケージ(具体的には、変換単位one.ctwo.c)を使用した変数の定義が複数あるため、リンクは失敗します。

からthree.c、両方の変数を同時に参照する方法はありませんx。一方または両方のモジュールで名前を変更するか、C++に切り替えて名前空間内xに少なくとも1つ配置する必要があります。x

于 2009-11-24T05:08:21.970 に答える
1

Cでは、次のことができます。

// one.c
static int x;
int *one_x = &x;

// two.c
static int x;
int *two_x = &x;

// three.c
extern int *one_x;
extern int *two_x;

これで、ファイル内またはファイル内のファイルxを明確に参照できます。one.cxtwo.cthree.c

ただし、これは価値があるよりも少し手間がかかる可能性があります。おそらく、Cの単一のグローバル名前空間を回避する理論的な方法をいじくり回すのではなく、グローバル変数のよりわかりやすい名前を考え出す必要があります。

于 2009-11-24T05:09:45.930 に答える
0

この質問への回答に興味があるかもしれません。

概要:リンカはファイルのリンクに失敗する場合と失敗しない場合があります。変数の初期化に依存します。変数の初期化がファイルごとに異なる場合は、間違いなく失敗します。

于 2009-11-24T05:03:55.177 に答える
0

グローバル静的変数を外部化できないことに注意してください.. !!

于 2009-11-24T07:49:19.587 に答える
0

シンボルの重複生成を回避するextern int x;には、1 つのヘッダー ファイル (.h ファイル) で宣言し、x を使用するすべての .c ファイルをそのヘッダー ファイルに含め、.c ファイルの1 つ#include定義または初期化する必要があります。int x;

于 2009-11-24T04:57:01.180 に答える