статический внешний против внешнего статический - PullRequest
3 голосов
/ 20 сентября 2011

Допустим, у меня есть только один файл в моем проекте с именем test.c; код ниже не компилируется, если я не определяю «ИСТИНА». Я просто хочу понять поведение. Пожалуйста, пролите немного света на этот аспект.

#ifdef TRUE
static int a;
extern int a;
#else
extern int a;
static int a;
#endif

int main (void)
{
  a =10;
  printf("%d", a);
  return 0;
}

Ответы [ 4 ]

6 голосов
/ 20 сентября 2011

Когда TRUE не определено, в первой декларации (extern) говорится, что a имеет внешнюю связь (ISO / IEC 9899: 1999, 6.2.2, пункт 4, предварительная декларация отсутствует). Во второй декларации (static) говорится, что a имеет внутреннюю связь (пункт 3). Идентификатор не может иметь как внутреннюю, так и внешнюю связь (пункт 7).

В определенном случае TRUE, extern во втором объявлении не имеет никакого значения, поскольку существует предварительное объявление, объявляющее a с внутренней связью (параграф 4).

См. черновик ISO / IEC 9899: 1999 .

3 голосов
/ 20 сентября 2011

Я не уверен, что вы пытаетесь сделать здесь, но вы повторно объявляете a как статическую и внешнюю переменные в другом порядке.

При применении к переменной static позволяет видеть глобальные переменные только в этом файле.extern объявляет внешнюю переменную, определенную в другом месте.Так, например, вы бы объявили a как extern, если он был первоначально определен в отдельном файле, и объявили бы его как static, если он должен быть видимым только внутри самого этого файла.

Вот ошибки:

test.c:8:12: error: static declaration of ‘a’ follows non-static declaration
test.c:7:12: note: previous declaration of ‘a’ was here

Вы объявляете a как внешнюю переменную (определенную в другом файле), но затем повторно объявляете ее как статическую, видимую только в этомfile.

В этом случае я бы рассмотрел, что означают эти классы хранения (extern, static и т. д.), а затем решил, как должна быть объявлена ​​ваша переменная.

0 голосов
/ 20 сентября 2011

Проблема здесь в том, что когда вы не определяете TRUE, используя #define TRUE, компилятор при выполнении части #else сначала обнаруживает объявление extern 'extern' переменной 'и начинает где-то ожидать ее объявление во внешней области видимости. Помните, что память для extern выделяется, когда программа начинает свое выполнение. Следовательно, он находит другое статическое определение после этого и пытается выделить память во время компиляции, но поскольку он не уверен в объявлении extern, возникает конфликт. Таким образом, ошибка генерируется как дубликат объявления.

Но когда истина определена и выполняется первое условие, «а» делается статическим перед объявлением extern и распределяет память прямо во время компиляции, и, следовательно, дальнейшие определения не конфликтуют. Надеюсь, это поможет. :)

Прочитать эту ссылку http://www.tenouk.com/ModuleZ.html

0 голосов
/ 20 сентября 2011

Когда вы определяете TRUE, вы объявляете a как extern, что означает, что определение a находится в каком-то другом файле, но компилятор не может его найти, поэтому он не может скомпилировать ваш файл.

Кроме того, я думаю, что вы написали неправильно вопрос, этот файл должен быть скомпилирован, когда вы не определяете TRUE.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...