Является ли пустой список инициализаций допустимым кодом 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 генерирует другой код сборки, но ведет себя одинаково.