2017-04-25 17 views
3

このコードはコンパイルされ、よく現在のC規格で定義されている:6.2:許可非静的宣言が続く静的宣言の根拠はなく、その逆

static int foo(int); 
extern int foo(int); 

標準は、この状況(C11内ことを指定します識別子の.2結合(P4)): その識別子の前に宣言が表示された範囲内のストレージクラス指定子はexternと宣言された識別子について

31) 前の宣言で内部または外部のリンケージが指定されている場合、後の宣言での識別子の連結は、前の宣言で指定された リンケージと同じです。 [...]

...これは、int foo(int)関数がstatic int foo(int)と宣言されていることを意味します。このように周りこれらの宣言を交換

extern int foo(int); 
static int foo(int); 

は...私はGNU GCCを使用してコンパイルエラーを与える: 'foo' での

static宣言が非static宣言

を次の

私の質問は、2番目のケースの背後にある設計の根拠はエラーで、1番目のケースと同様に扱われないのは何ですか?私はそれは別の翻訳単位が管理しやすく、そして#includeという事実と関係があると思われますか?私はこれを理解していないかのように、将来のCプロジェクトでいくつかの間違いに気づくことができるように感じます。

+0

コメントが間違っている ''int型のfoo(int型)'関数は ''はextern int型のfoo(int型)と宣言されていることを意味':。あなたがstaticを使用する場合は、新しい何かを宣言するのに対し従来の 'static'宣言は、関数が'静的 'であることを意味します。ヘッダー(宣言が属している)に外部から見える関数を宣言し、ソースファイル内の静的関数のみを宣言すれば、問題は発生しません。ヘッダーは静的関数を宣言しません(ヘッダーが静的インライン関数を定義しない限り)。あなたがコードを書いているように厄介な場合にのみ、問題にぶつかることができます。 Cコンパイラを使用すると、厄介なことができますが、そうではありません。 –

+0

同様のコメントが変数に適用されます。ソースファイルに 'extern'宣言を記述しないでください。ヘッダーファイルにのみ属します。 –

+0

@JonathanLeffler "以前の静的宣言は、関数が静的であることを意味します"。それは正解です、それはタイプミスでした。編集されました。 –

答えて

1

私はこの混乱仕様のアイデアはextern宣言は

static double a; // a declaration and definition 

void func(void) { 
    unsigned a; 
    ..... 
    if (something) { 
    extern double a; // refers to the file scope object 

    } 
} 

同じ名前を持つ別の識別子からそれを明確にするなど、グローバル関数やオブジェクトを参照するために関数の内部で使用することができることであると思います

extern double a; // just a declaration, not a definition 
        // may reside elsewhere 
void func(void) { 
    unsigned a; 
    ..... 
    if (something) { 
    static double a; // declares and defines a new object 

    } 
} 
+0

意味があります。他人が最初に言うことを見たいと思っていますが、これまでのところこれがもっともらしいと思います。 –

関連する問題