Порядок инициализации для нескольких деклараторов в одной декларации

Просто просмотрел C99 и C11, пытаясь выяснить, гарантируют ли они, что несколько деклараторов в одном объявлении выполняются по порядку слева направо. Они говорят, что каждый полный декларатор заканчивается в точке последовательности

6.7.5 C99 Деклараторы

6.7.6 C11 Деклараторы

3 Полный декларатор является декларатором, который не является частью другого декларатора. Конец полного декларатора является точкой последовательности. [...]

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

int main() {
  int i = 0;
  int a = i++, b = i++;
  // Are values of `a` and `b` specified here?
}

Если порядок не указан, он запрещает следующий шаблон реализации

int array[N];
for (int *element = array, *element_end = element + N; 
     element != element_end; 
     ++element)
  *element = 0;

который кажется мне удивительным. (Я понимаю, что вместо element_end можно инициализировать array + N.)

P.S. Спецификация С++ не является точно выраженной в этом отношении. В нем есть сноска, в которой говорится, что T d1, d2; эквивалентно T d1; T d2;, но они ненормативны. Следовательно, очевидно, что DR # 1342

Ответы

Ответ 1

Я не знаю, как я это пропустил, учитывая, что я действительно искал весь документ для слова "порядок", но он действительно там

6.8 C99 Заявления и блоки

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

Ответ 2

Неужели это неуточненно, или я пропустил что-то простое?

Заказ не указан. Это связано с тем, что , в

 int a = i++, b = i++;

действуют как разделитель, а не как оператор. Порядок инициализации здесь не гарантируется.

Ответ 3

Итак, вот оно. если начальное значение предположительно равно 0, то а будет присвоено значение: 1. B также будет присвоен 1, потому что значение я не изменилось. На этом этапе назначаются значения a и b.

Вы можете проверить с помощью инструкции printf. a = я ++ означает, что значение a равно я + 1.

Точно так же b также дается я + 1.