Интересный вопрос возник как побочный эффект какого-то другого вопроса о возможных различиях между тем, как C и C ++ обрабатывают (non-stati c -storage-duration):
int arr[7] = {0};
Кто-то утверждал, что в C ++ другие элементы не гарантировались равными нулю, но я не уверен, что согласен.
Теперь C11 заявляет, в 6.7.9 Initialization /19
:
Инициализация должна происходить в порядке списка инициализаторов, каждый инициализатор предоставляется для определенного подобъекта, перекрывая любой ранее перечисленный инициализатор для того же подобъекта; все подобъекты, которые не были инициализированы явно, должны быть неявно инициализированы так же, как и объекты, у которых есть c продолжительность хранения.
Это означает, что другие шесть элементов arr
будут инициализированы нулями (поскольку static int x;
инициализирует x
нулями).
Я не уверен, так ли это для C ++. В стандарте C ++ 20 9.3.1 Aggregates /3
гласит:
Когда агрегат инициализируется списком инициализаторов, как указано в 9.3.4
, элементы списка инициализаторов принимаются в качестве инициализаторов для элементы совокупности. Явно инициализированные элементы агрегата определяются следующим образом:
(3.1) - (несущественные вещи, связанные с назначенными списками и классами инициализатора - pax).
(3.2) - Если инициализатор list - список инициализаторов, явно инициализированные элементы агрегата являются первыми n
элементами агрегата, где n
- количество элементов в списке инициализатора.
Тогда /4
указывает, как работает явная инициализация, и /5
обрабатывает неявные случаи:
Для агрегата без объединения каждый элемент, который не был явно инициализирован элемент инициализируется следующим образом:
(5.1) - если элемент имеет инициализатор члена по умолчанию (10.3), элемент инициализируется из этого инициализатора.
(5.2) - в противном случае, если Элемент не является ссылкой, элемент инициализируется копией из пустого списка инициализатора (9.3.4).
(5.3) - В противном случае программа не работает ormed.
Мне кажется, что наш конкретный случай покрыт (5.2)
, поэтому нам нужно от go до 9.3.4
, чтобы увидеть, что происходит с int
, инициализированным с пустым списком. ({}
). Это происходит во многих случаях, но я считаю, что первое, что соответствует:
(3.11) - В противном случае, если в списке инициализатора нет элементов, объект инициализируется значением.
И от 9.3 Initializers /8
:
Инициализация значения объекта типа T означает:
(8.1) - если T является (возможно, cv -квалифицированный) тип класса (раздел 10) без конструктора по умолчанию (10.3.4) или конструктора по умолчанию, предоставленного или удаленного пользователем, тогда объект инициализируется по умолчанию;
(8.2) - если T является (возможно, cv-квалифицированным) типом класса без предоставленного пользователем или удаленного конструктора по умолчанию, тогда объект инициализируется нулями и проверяются ограничения semanti c для инициализации по умолчанию, и если T имеет нетривиальный конструктор по умолчанию, объект инициализируется по умолчанию;
(8.3) - если T является типом массива, то каждый элемент инициализируется значением;
(8.4) - в противном случае объект является инициализируется нулями.
* 10 79 * Следовательно, это
8.4
, которое, по-видимому, является управляющим предложением, а это означает, что C ++
также инициализирует неявные элементы массива в ноль.
Верны ли мои рассуждения? Сможет ли C ++ при обнаружении int arr[7] = {0};
установить все элементы на ноль?