0

extern の次の動作には驚かされます。

これを実行すると

#include<stdio.h>
int main()
{
    extern int a;
    printf("%d\n", a);
    return 0;
}
int a=20;

出力: 20 (gcc Linux 32 ビットでは問題ないようです)

しかし、a内部で変数を宣言するとmain():

#include<stdio.h>
int main()
{
    extern int a;
    int a=20;
    printf("%d\n", a);
    return 0;
}

出力:

extern.c: In function ‘main’:
extern.c:5:9: error: declaration of ‘a’ with no linkage follows extern declaration
extern.c:4:16: note: previous declaration of ‘a’ was here

のスコープをaグローバルからローカルに変更した後、エラーが発生するのはなぜですか?a以前のケースでは許可されていたの再宣言が許可されないのはなぜですか?

4

2 に答える 2

7

宣言のポイントは、複数のコンパイル ユニット (ファイル) で使用されているが、1 つのコンパイル ユニットで定義および割り当てられてexternいるグローバル変数または関数についてコンパイラに通知することです。.c宣言はすべてのexternユニットに含まれるヘッダー ファイルに配置され、1 つのコンパイル ユニットに実際の定義が含まれるため、両方が表示されます。

最初の例は正当な C です。外部で定義された変数を参照することを宣言してから、現在のコンパイル単位でその変数の定義aに進みます。通常、宣言はヘッダー ファイルからインクルードされるため、コンパイラには関数内ではなく最上位に表示されますが、コンパイラはどちらの方法も気にしません。つまり、ここでは再定義はなく、宣言に続く定義のみですextern

2 番目の例aでは、外部リンケージを持つことを宣言し、それをローカル変数として定義しますmain。宣言と定義は明らかに互換性aがありません。 がローカル変数の場合、1 か所だけで定義して割り当てることはできません。代わりに、関数が呼び出されるたびに自動的にスタックに割り当てられます。この非互換性により、エラー診断が発生します。

于 2013-09-15T07:03:18.637 に答える