C99 Структура Назначенные инициализаторы и другая ценность

Мне известно, что в C99 вы можете инициализировать элементы структуры, используя имя члена следующим образом:

struct myStruct
{
 int i;
 char c;
 float f;
};

Следующее действительно:

struct myStruct m = {.f = 10.11, .i = 5, .c = 'a'};

Также сказано, что неинициализированные члены будут настроены на 0, Так

struct myStruct m = {.f = 10.11, .c = 'a'};

Вот i будет установлен в 0

Но для следующего:

struct myStruct m = {.f = 10.11, .c = 'a', 6}; 

i все еще инициализируется до 0. Что является причиной, если мы делаем такую ​​сложную инициализацию.

3 ответа

Решение

Это описано в разделе проекта стандарта C99. 6.7.8 Инициализация, в основном, если следующий инициализатор не является указателем, тогда он выберет следующее поле после этого указателя, которое для ваших примеров будет f, Мы можем посмотреть на пункт 17, который говорит (выделение мое):

Каждый заключенный в скобки список инициализаторов имеет связанный текущий объект. Когда нет обозначений, подобъекты текущего объекта инициализируются в порядке, соответствующем типу текущего объекта: элементы массива в порядке возрастания индекса, элементы структуры в порядке объявления и первый именованный член объединения.129), обозначение заставляет следующий инициализатор начать инициализацию подобъекта, описанного указателем. Затем инициализация продолжается по порядку, начиная со следующего подобъекта после того, что описано указателем.130)

Зачем i инициализируется в 0 рассматривается в параграфе 19, где говорится:

Инициализация должна происходить в порядке списка инициализаторов, каждый инициализатор предоставляется для конкретного подобъекта, переопределяя любой ранее перечисленный инициализатор для того же подобъекта;132) все подобъекты, которые не инициализированы явно, должны быть неявно инициализированы так же, как объекты, которые имеют статическую продолжительность хранения.

Обратите внимание, что, как указывает Кит gcc предоставляет предупреждение для этого с помощью -Wextra:

warning: initialized field overwritten [-Woverride-init]
 struct myStruct m = {.f = 10.11, .c = 'a', 6}; 
        ^

а также clang кажется, предупреждает об этом по умолчанию.

В случае

struct myStruct = {.f = 10.11, .c = 'a', 6};   

Значение 6 который является неназначенным инициализатором, будет назначен члену сразу после того, как член инициализирован назначенным инициализатором. Итак, в этом случае член f только после c и, следовательно, он будет инициализирован в 6, i все еще будет инициализирован в 0 по умолчанию.

Здесь 6 - не обозначенный инициализатор. Таким образом, это значение инициализируется для члена сразу после предыдущего назначенного инициализатора, то есть с плавающей точкой сразу после символа.

Если у вас было два или более неназначенных инициализатора в серии, то неназначенные инициализаторы будут инициализированы для членов в серии из последнего назначенного инициализатора.

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