Имам следната 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 Идентификатор, деклариран в различни обхвати или в един и същ обхват повече от веднъж, може да бъде направен така, че да препраща към един и същ обект или функция чрез процес, наречен свързване.21) Има три вида свързване: външно, вътрешно и никакво.
2 В набора от единици за превод и библиотеки, които представляват цяла програма, всяка декларация на конкретен идентификатор с външна връзка обозначава един и същ обект или функция. В рамките на една единица за превод всяка декларация на идентификатор с вътрешна връзка обозначава един и същ обект или функция. Всяка декларация на идентификатор без връзка обозначава уникален обект.
3 Ако декларацията на идентификатор на обхват на файл за обект или функция съдържа статичен спецификатор на клас за съхранение, идентификаторът има вътрешна връзка.22)
4 За идентификатор, деклариран със спецификатора на класа за съхранение extern в обхват, в който е видима предишна декларация на този идентификатор,23), ако предишната декларация указва вътрешна или външна връзка, връзката на идентификатора в по-късната декларация е същата като връзката, посочена в предишната декларация. Ако не се вижда предходна декларация или ако предходната декларация не посочва връзка, тогава идентификаторът има външна връзка.
5 Ако декларацията на идентификатор за функция няма спецификатор на клас за съхранение, нейната връзка се определя точно така, както ако беше декларирана със спецификатора на клас за съхранение extern. Ако декларацията на идентификатор за обект има файлов обхват и няма спецификатор на клас за съхранение, връзката му е външна.
6 Следните идентификатори нямат връзка: идентификатор, деклариран като нещо различно от обект или функция; идентификатор, деклариран като функционален параметър; идентификатор на обхват на блок за обект, деклариран без спецификатора на класа за съхранение extern.
7 Ако в рамките на единица за транслация един и същи идентификатор се появи както с вътрешна, така и с външна връзка, поведението е недефинирано.
21) Няма връзка между различните идентификатори. 22) Декларацията на функция може да съдържа статичен спецификатор на клас за съхранение само ако е в обхвата на файла; виж 6.7.1.
В.1 Не мога да разбера правило 4 и 5? между другото каква е разликата връзката се определя точно така, както ако беше декларирана със спецификатора на класа за съхранение extern. и връзката е външна
Q2. защо идва тази грешка, тъй като мога да заключа от правило 5, че c има static decl. последвано от extern decl. така че последното декламиране също трябва да бъде статично.? Ще съм благодарен, ако някой си положи труда да обясни всички правила от самото начало..или ми предложи връзка, която обяснява ясно всички правила.*
Забележка: благодаря за всякакви предложения за правилно редактиране на този въпрос, защото може да се дублира, зададох този въпрос, тъй като не можах да разбера отговорите на подобни въпроси, публикувани на този сайт, благодаря предварително.