Является ли пустой список инициализаций допустимым кодом C?
Обычно используется {0}
для инициализации struct
или array
, но рассмотрим случай, когда первое поле не является скалярным типом. Если первым полем struct Person
является другой struct
или массив, то эта строка приведет к ошибке (error: missing braces around initializer
).
struct Person person = {0};
По крайней мере GCC позволяет мне использовать пустой список инициализаций для выполнения того же самого
struct Person person = {};
Но этот допустимый C-код?
Также: гарантируется ли эта строка тем же самым поведением, то есть нулевой инициализированный struct
?
struct Person person;
Ответы
Ответ 1
Нет, пустой список инициализаторов не разрешен. Это также может быть показано GCC при компиляции с помощью -std=c99 -pedantic
:
a.c:4: warning: ISO C forbids empty initializer braces
Причина заключается в том, как грамматика определена в §6.7.9 стандарта 2011 ISO C:
initializer:
assignment-expression
{ initializer-list }
{ initializer-list , }
initializer-list:
designation(opt) initializer
initializer-list , designation(opt) initializer
В соответствии с этим определением список инициализаторов должен содержать хотя бы один инициализатор.
Ответ 2
Согласно стандарту C99, создание массива с пустым списком инициализаторов запрещено. В предыдущем ответе вы можете видеть, что грамматика не описывает этот случай.
Но что произойдет, если вы объявите массив без инициализации? Ну, это зависит от компилятора, который вы используете. Давайте посмотрим на этот простой пример: int arr[5] = {}
.
НКУ
По умолчанию gcc
не выдает никаких предупреждений/ошибок при попытке скомпилировать этот код. Даже -Wall
, но -Wpedantic
делает.
warning: ISO C forbids empty initializer braces
Но в любом случае gcc
заполняет члены массива 0 точно так, как если бы вы указали его явно int arr[5] = {0}
см. Godbolt вывода сборки.
лязг
Но по умолчанию не отображаются предупреждения об этом случае, но с параметром -Wgnu-empty-initializer
делает:
warning: use of GNU empty initializer extension
Clang генерирует другой код сборки, но ведет себя одинаково.