Что значит объявить переменную со спецификатором класса хранения, но без спецификатора типа?

Прочитав спецификацию грамматики ANSI C Yacc, я заметил все следующие действительны:

register x;
auto y;
static z;
extern q;

Мне это кажется странным, поскольку мое понимание типа предполагает, что ни одна из этих переменных не имеет типа. Что это значит? Как они проверяются? Сколько памяти выделено?


person user1547129    schedule 26.01.2014    source источник
comment
Введите значение по умолчанию int.   -  person Joseph Quinsey    schedule 26.01.2014
comment
Мне любопытно, какую спецификацию вы читаете?   -  person Shafik Yaghmour    schedule 26.01.2014
comment
Не забывайте unsigned w. Я работаю в кодовой базе, которая широко использует эту идиому.   -  person StilesCrisis    schedule 26.01.2014
comment
@ShafikYaghmour Я читаю спецификацию грамматики yacc/bison здесь< /а>.   -  person user1547129    schedule 26.01.2014


Ответы (1)


До C99, если тип не был указан, по умолчанию использовался int, это должно было быть удалено в C99, но многие компиляторы поддерживают его даже в режиме C99. Например, в clang даже при использовании -std=c99 я получаю только следующие предупреждения, а не ошибки:

warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  register x;
  ~~~~~~~~ ^
warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  auto y;
  ~~~~ ^
warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  static z;
  ~~~~~~ ^
warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
  extern q;
  ~~~~~~ ^

gcc также выдает только предупреждение в этом случае, хотя использование флага -pedantic-errors приведет к тому, что gcc выдаст ошибки, которые обычно имеют место для расширений в gcc и обычно для clang, но не в этом случае.

Если мы посмотрим на проект стандарта C99, В разделе Вперед говорится:

[...] Основные изменения по сравнению с предыдущим изданием включают:

и включает в себя следующий пункт:

— удалить неявный int

Обновить

Из Обоснование международного стандарта — Языки программирования — C раздел 6.7.2 Спецификаторы типов:

новая функция C99: в C89 все спецификаторы типов могут быть исключены из спецификаторов объявления в объявлении. В таком случае подразумевалось int. Комитет решил, что опасность, присущая этой функции, перевешивает ее удобство, и поэтому она была удалена. В результате гарантируется создание диагностики, которая выявит дополнительную категорию ошибок программирования. После выдачи диагностики реализация может принять неявное значение int и продолжить трансляцию программы для поддержки существующего исходного кода, использующего эту функцию.

Используемая вами грамматика действительно предшествует C99, но, насколько я могу судить, это новая версия, обновленная с учетом C11 не сильно отличается в отношении спецификаторов типа в объявлении. Таким образом, грамматика в этой ситуации недостаточна для обеспечения соблюдения этого ограничения. Вам нужно будет перейти в стандартный раздел 6.7.2 Спецификаторы типов и увидеть, что там написано:

По крайней мере, один спецификатор типа должен быть указан в спецификаторах объявлений в каждом объявлении и в списке спецификаторов-квалификаторов в каждом объявлении структуры и имени типа.

person Shafik Yaghmour    schedule 26.01.2014