У меня есть следующая программа 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.
Q.1 Я не могу понять правила 4 и 5? в чем разница между привязкой определяется точно так же, как если бы она была объявлена с помощью спецификатора класса хранения extern. и привязка является внешней
Q2. почему возникает эта ошибка, поскольку я могу сделать вывод из правила 5, что c имеет static decl. за которым следует extern decl. так что последний decl.shud тоже будет статическим.? Я буду рад, если кто-то изо всех сил объяснит все правила с самого начала ... или предложит мне ссылку, которая четко объясняет все правила *.
Примечание: спасибо за любые предложения по правильному редактированию этого вопроса, потому что он может дублироваться. Я задал этот вопрос, потому что я не мог заранее понять ответы на похожие вопросы, размещенные на этом сайте.