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

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

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

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

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 Введите спецификаторы и посмотрите, что там написано:

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

Другие вопросы по тегам