Expressions and statements
ES.44
Не зависьте от порядка вычисления аргументов функции
Причина
Этот порядок не определён.
Примечание
C++17 ужесточает правила порядка вычислений, но порядок вычисления аргументов функции по-прежнему не определён.
Пример
int i = 0;
f(++i, ++i);
До C++17 поведение не определено, поэтому оно могло быть любым (например, f(2, 2)). Начиная с C++17, этот код не имеет неопределённого поведения, но по-прежнему не определено, какой аргумент вычисляется первым. Вызов будет f(1, 2) или f(2, 1), но вы не знаете, каким именно.
Пример
Перегруженные операторы могут приводить к проблемам порядка вычислений:
f1()->m(f2()); // m(f1(), f2())
cout << f1() << f2(); // operator<<(operator<<(cout, f1()), f2())
В C++17 эти примеры работают как ожидается (слева направо), а присваивания вычисляются справа налево (так же, как связывание = происходит справа налево):
f1() = f2(); // неопределённое поведение в C++14; в C++17 f2() вычисляется до f1()
Контроль
Может быть обнаружен хорошим анализатором.