Инициализация структуры до 0

Если у меня есть такая структура:

typedef struct
{
    unsigned char c1;
    unsigned char c2;
} myStruct;

Каким будет самый простой способ инициализировать эту структуру до 0? Было бы достаточно?

myStruct _m1 = {0};

или мне нужно будет явно инициализировать каждый член до 0?

myStruct _m2 = {0,0};

Ответ 1

Первое проще всего (включает в себя меньше ввода текста), и он гарантированно работает, все члены будут установлены в 0 [Ref 1].
Второй - более читаемый.

Выбор зависит от предпочтений пользователя или от того, который соответствует вашему стандарту кодирования.

[Ссылка 1] Ссылка C99 Стандарт 6.7.8.21:

Если в списке, заключенном в скобках, меньше инициализаторов, чем в элементе или элементах совокупности или меньше символов в строковом литерале, используемом для инициализации массива с известным размером, чем в массиве, остальная часть агрегат должен быть инициализирован неявным образом так же, как объекты, имеющие статическую продолжительность хранения.

Хорошее чтение:
C и С++: частичная инициализация автоматической структуры

Ответ 2

Если данные представляют собой статическую или глобальную переменную, она по умолчанию заполняется нулем, поэтому просто объявите ее myStruct _m;

Если данные представляют собой локальную переменную или выделенную кучей зону, очистите ее с помощью memset как:

memset(&m, 0, sizeof(myStruct));

Текущие компиляторы (например, последние версии gcc) оптимизируют это на практике. Это работает только в том случае, если все нулевые значения (включая нулевые указатели и ноль с плавающей точкой) представлены как все нулевые биты, что верно для всех платформ, о которых я знаю (но стандарт C разрешает реализации, где это ложь, я не знаю такой реализации).

Возможно, вы можете ввести код myStruct m = {}; (который может быть принят как расширение), но я нахожу это довольно уродливым. И если первый член структуры не является скалярным, т.е. Является объединением, структурой или массивом, тогда некорректное кодирование myStruct m = {0};.

Я чувствую, что использование memset для локальных структур является лучшим, и это лучше говорит о том, что во время выполнения необходимо что-то сделать (в то время как обычно глобальные и статические данные можно понимать как инициализированные во время компиляции, без каких-либо затрат во время выполнения).

Ответ 3

См. §6.7.9 Инициализация:

21 Если в списке, заключенном в фигурные скобки, меньше инициализаторов, чем элементов или элементов совокупности или меньше символов в строковом литерале, используемом для инициализации массива известных размера, чем есть элементы в массиве, остальная часть совокупности должна быть инициализируется неявно так же, как и объекты, имеющие статическую продолжительность хранения.

Итак, да, оба они работают. Обратите внимание, что в C99 также может быть использован новый способ инициализации, называемый назначенной инициализацией:

myStruct _m1 = {.c2 = 0, .c1 = 1};