Во-первых, современный C++ перешел от старого (неадекватной) концепции «точек последовательности» в новая концепция «секвенирования» (т.е. «секвенирована раньше», «упорядочена после»). Пока i = i++
по-прежнему не определено, i = ++i
на самом деле отлично определено сейчас. Правила секвенирования во многих возвращающих lvalue операциях были переработаны.
Во-вторых, ваша версия безопасна по старой спецификации, а также по новой. Модификация i
внутри функции безопасно «изолирована» от назначения до i
снаружи. В классических точках последовательности функций в начале и в конце функции безопасно отделяются изменения (и чтения) от i
друг от друга. Новые правила последовательности сохраняют тот же уровень защиты.
Пример, который иллюстрирует защиту, обеспечиваемую вызов функции может выглядеть следующим образом
int inc(int &i) { return i++; }
...
int i = 1;
int r1 = i++ * i++ * i++;
// Undefined behavior because of multiple unsequenced side effects
// applied to the same variable
int r2 = inc(i) * inc(i) + inc(i);
// No UB, but order of evaluation is unspecified. Since the result
// depends on the order of evaluation, it is unspecified
int r3 = inc(i) + inc(i) + inc(i);
// Perfectly defined result. Order of evaluation is still unspecified,
// but the result does not depend on it
, что говорит компилятор? – tristan
@tristan, как правило, компилятор ничего не говорит о UB. – user2079303
gcc имеет опцию «-Последняя точка» – tristan