次のCプログラムがあります:
#include<stdio.h>
static void p(void);
static int c;
int main(int argc,char **argv) {
p();
printf("%d",c);
return 0;
}
void p(void) {
printf("From the Function P\n");
}
int c=232;
そして、コンパイラ gcc の出力エラーは次のとおりです。 エラー: 'c' の非静的宣言は、静的宣言に従います
そして、私がC標準ISO/IEC 9899:TC2を見たとき:
6.2.2 識別子のリンケージ
1 異なるスコープまたは同じスコープで 2 回以上宣言された識別子は、リンケージと呼ばれるプロセスによって同じオブジェクトまたは関数を参照することができます 21)。
2 プログラム全体を構成する翻訳単位とライブラリのセットでは、外部リンケージを持つ特定の識別子の各宣言は、同じオブジェクトまたは関数を示します。1 つの翻訳単位内で、内部リンケージを持つ識別子の各宣言は、同じオブジェクトまたは関数を表します。リンクのない識別子の各宣言は、一意のエンティティを示します。
3 オブジェクトまたは関数のファイル スコープ識別子の宣言にストレージ クラス指定子 static が含まれている場合、識別子は内部リンケージを持ちます。
4 その識別子の前の宣言が可視であるスコープ内で ストレージクラス指定子 externで宣言された識別子の場合、23) 前の宣言が内部リンケージまたは外部リンケージを指定する場合、後の宣言での識別子のリンケージは同じです。前の宣言で指定されたリンケージとして。前の宣言が表示されない場合、または前の宣言でリンケージが指定されていない場合、識別子には外部リンケージがあります。
5関数の識別子の宣言にストレージ クラス指定子がない場合、そのリンケージは、ストレージ クラス指定子 extern で宣言されているかのように正確に決定されます。オブジェクトの識別子の宣言にファイル スコープがあり、ストレージ クラス指定子がない場合、そのリンケージは externalです。
6 次の識別子にはリンケージがありません。オブジェクトまたは関数以外のものとして宣言された識別子。関数パラメーターとして宣言された識別子。ストレージ クラス指定子 extern なしで宣言されたオブジェクトのブロック スコープ識別子。
7 翻訳単位内で、同じ識別子が内部リンケージと外部リンケージの両方に現れる場合、動作は未定義です。
21) 異なる識別子間のリンクはありません。22) 関数宣言は、ファイル スコープにある場合にのみ、ストレージ クラス指定子 static を含むことができます。6.7.1 を参照。
Q.1 ルール 4 と 5 がわからないのですが?違いは何ですかリンケージは、ストレージクラス指定子 extern で宣言されているかのように正確に決定されます。そしてリンケージは外部です
Q2. なぜこのエラーが発生するのか、ルール 5 から c に static decl があると推測できるからです。その後に extern decl が続きます。最後のdecl.shudも静的です。誰かが最初からすべてのルールを説明するのに苦労している場合は感謝します..または、すべてのルールを明確に説明するリンクを提案してください.*
注:この質問を適切に編集するための提案については、重複する可能性があるため、このサイトに投稿された同様の質問の回答を事前に理解できなかったため、この質問をしました。