Подтвердить что ты не робот

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. В чем причина, если мы выполняем такую ​​сложную инициализацию.

4b9b3361

Ответ 1

Это описано в стандартном разделе проекта 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, похоже, предупреждают об этом по умолчанию.

Ответ 2

В случае

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

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

Ответ 3

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

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