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