Что значит объявить переменную со спецификатором класса хранилища, но без спецификатора типа?
После прочтения спецификации грамматики 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
Введите спецификаторы и посмотрите, что там написано:
По крайней мере, один спецификатор типа должен быть указан в спецификаторах объявлений в каждом объявлении и в списке спецификаторов-спецификаторов в каждом объявлении структуры и имени типа.