i = v[i++]; // the behavior is unspecifiedРассмотрим предпоследнее выражение. Допустим, изначально i=0. Интересно, что интуитивно выражение i = ++i + 1 абсолютно определено и непонятно как создатели компилятора могут выдать что-то кроме 2. Однако, стандарт позволяет в реализации делать отложенную запись вычислений. Т. е. в этом последнем примере может быть такая реализация:
i = 7, i++, i++; // i becomes 9
i = ++i + 1; // the behavior is unspecified
i = i + 1; // the value of i is incremented
- Посчитали значение ++i и запомнили в регистре (в переменную i результат запишем позднее).
- Считаем результат ++i + 1, взяв результат п. 1.
- Записываем в i значение, которое посчитали в п. 2.
- О, чуть не забыли. Записываем результат п. 1 в переменную i.
Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored. The requirements of this paragraph shall be met for each allowable ordering of the subexpressions of a full expression; otherwise the behavior is undefined.В отладочном режиме такого, скорее всего не будет, но при оптимизации очень может быть. Для разработчиков это означает, что, если в выражении переменная меняется более одного раза, то это скорее всего приведет к нежелательным последствиям и трудноуловимым багам.
Ссылки по теме:
Why is `i = ++i + 1` unspecified behavior?
Точки следования (sequence points)