Итак, я прочитал здесь: https://stackoverflow.com/a/598150/2642059 что это незаконно
foo(i++, i++);
Но я полагаю, что это потому, что нет принудительной последовательности, что, как я понимаю, относится к спискам инициализаторов. Так это правовой кодекс?
const int foo[] = { i++, i++ };
Да, порядок вычисления предложений инициализатора гарантирован в braced-init-list.
Из стандарта, §11.6.4 / 4 Список-инициализация [dcl.init.list]:
(акцент мой)
В пределах списка инициализатора списка фигурных скобок
пункты-инициализаторы, включая те, которые являются результатом расширений пакета,
оцениваются в порядке их появления. То есть каждое значение
вычисления и побочный эффект, связанный с данным предложением инициализатора
последовательность перед каждое вычисление значения и связанный побочный эффект
с любым пунктом инициализатора, который следует за ним в запятом
список инициализатора-списка. [Примечание: этот порядок оценки
независимо от семантики инициализации; например, это
применяется, когда элементы списка инициализатора интерпретируются как
аргументы вызова конструктора, хотя обычно нет
ограничения последовательности на аргументы вызова. — конец примечания]
От cppreference.com:
Каждое предложение инициализатора последовательный
до любой
Предложение инициализатора, которое следует за ним в списке фигурных скобок. Это в
контрастировать с аргументами вызов функции
выражение,
которые
unsequenced.
Пример для примечания стандарта,
struct A { A(int, int) {} };
...
int i = 0;
A a1(i++, i++); // used as the arguments of the constructor; unsequenced
A a2{i++, i++}; // used as the arguments of the constructor; sequenced, within the initializer-list of a braced-init-list
Других решений пока нет …