Гарантированно ли неинициализированные элементы частично определенных статических объектов инициализированы до 0?

Я знаю, что неинициализированные статические переменные хранятся в BSS и, следовательно, гарантированно инициализируются со всеми 0 (для их соответствующего размера типа данных).

Кроме того, в C статические переменные могут быть определены как константы времени компиляции (только).

Каково определенное поведение "частично инициализированных" статических переменных (я не уверен, что это правильный термин), как показано в следующем примере:

// main.c

#include <stdbool.h>
#include <stdio.h>

static struct Foo
{
  bool f[2][3];
} g_table =      { { { true, true, false },
                     { true } } };

int main( int argc, char* argv[] )
{
  printf( "%d %d %d\n", g_table.f[0][0], g_table.f[0][1], g_table.f[0][2] );
  printf( "%d %d %d\n", g_table.f[1][0], g_table.f[1][1], g_table.f[1][2] );
  return 0;
}

.

$ gcc --version && gcc -g ./main.c && ./a.out 
gcc (GCC) 9.2.1 20190827 (Red Hat 9.2.1-1)
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

1 1 0
1 0 0

Под «частично инициализированным» выше я подразумеваю инициализацию g_table, где не все элементы массива элементов определены явно. В приведенном выше примере подразумевается, что неинициализированные явно части статического объекта g_table инициализируются 0. Это гарантированное/определенное поведение?


Примечание. Мне известно, что существуют вопросы о переполнении стека, касающиеся инициализации статических переменных и значения по умолчанию для неинициализированных статических переменных; Мне не удалось найти существующий вопрос относительно этой «частичной инициализации» (пожалуйста, дайте мне знать, если существует более правильный термин для того, что я описываю).


person StoneThrow    schedule 28.01.2020    source источник
comment
любой объект, который частично инициализирован, имеет оставшуюся часть полностью инициализированной по умолчанию, статической или нет.   -  person Antti Haapala    schedule 29.01.2020


Ответы (1)


Все остальные элементы инициализируются нулем (для арифметических типов) или нулевым указателем (для указателей). C 2018 6.7.9 21 говорит:

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

6.7.9 10 говорит, что объекты со статической продолжительностью хранения фактически инициализируются нулем:

… Если объект со статической или потоковой длительностью хранения не инициализирован явно, то:

— если он имеет тип указателя, он инициализируется нулевым указателем;

— если он имеет арифметический тип, он инициализируется (положительным или беззнаковым) нулем;

— если это агрегат, то каждый элемент инициализируется (рекурсивно) в соответствии с этими правилами, а любое заполнение инициализируется нулевыми битами;

- если это объединение, первый именованный элемент инициализируется (рекурсивно) в соответствии с этими правилами, а любое заполнение инициализируется нулевыми битами;

person Eric Postpischil    schedule 28.01.2020