В C существует несколько способов инициализации структур:
struct Point { int x, y; }; struct Point p = {10, 20};
Поля инициализируются в объявленном порядке.
struct Point p = {.y = 20, .x = 10};
Можно инициализировать поля в любом порядке.
struct Rect { int x, y, w, h; } r = {1, 2}; // w и h == 0
struct Color { int r, g, b; }; struct Pixel { struct Point pos; struct Color col; }; struct Pixel px = {{10,20}, {255,0,0}};
Именованная инициализация поможет избежать ошибок:
struct Pixel px = {.col = {.r = 255, .g = 0, .b = 0}};
Подводные камни:
Вопрос: Что будет, если при инициализации структуры в ней явно не указать все поля, и структура объявлена как автоматическая локальная переменная?
Ожидаемо неверный ответ: "Оставшиеся поля всегда будут равны нулю."
Правильный ответ: Автоматические (локальные) переменные, неинициализированные явно, остаются с неинициализированными значениями. Частичная инициализация инициализирует только явно прописанные поля, остальные — неопределённое значение (за исключением инициализации через = {...}, где остальные будут нулевыми только для статических/глобальных структур).
Пример:
void foo() { struct Point { int x, y, z; } p = {1}; // p.x == 1, p.y и p.z == 0 (Только через = {1};) }
История
В проекте графического движка добавили поле в начало структуры вершины, не пересмотрев общий способ инициализации объектов в разных модулях. В результате половина модулей стала неверно инициализировать цвет или координаты, что проявилось в виде артефактов отображения.
История
В обработчике видео структура с вложенными указателями частично инициализировалась = {0}, что корректно для глобальных переменных, но не для локальных. В итоге указатели содержали «мусор», что привело к работе с невалидными адресами и тяжелоуловимым сбоям.
История
При добавлении новых полей в большую структуру авторы не обновили старые участки кода с порядковой инициализацией. Из-за несовпадения порядка полей и инициализаторов критические переменные стали получать некорректные значения. Найти причину помог только аудит структуры и внедрение именованной инициализации.