В языке C операции постфиксного (i++) и префиксного (++i) инкремента увеличивают значение переменной на 1, но возвращаемое значение отличается:
Пример:
int i = 5; int a = i++; // a == 5, i == 6 int j = 5; int b = ++j; // b == 6, j == 6
В простых выражениях разница несущественна, но в сложных (например, с несколькими инкрементами за раз) может возникнуть неопределённое поведение.
Какое будет значение переменной a после выполнения выражения
int a = i++ + ++i;, еслиi = 1?
Вычисление зависит от порядка вычисления операндов, который стандарт не гарантирует, а также приводит к неопределённому поведению (undefined behavior), потому что переменная i модифицируется более одного раза между последовательным использованием значения. Так писать нельзя!
Пример такого кода:
int i = 1; int a = i++ + ++i; // неопределённое поведение! Не используйте так!
История
В крупном проекте расчет индекса в массиве писался как arr[i++] = getValue(++i); — разработчик хотел сохранить старое значение, одновременно получить новое. На разных компиляторах поведение отличалось: иногда одно значение затирало другое, иногда программа крашилась. Причина — недопустимые множественные изменения i в одном выражении.
История
В embedded-проекте значение счетчика увеличивалось как часть сложного выражения: if (buffer[i++] == TERMINATOR && ++i < SIZE) ... — на «железе» иногда получался неверный индекс из-за разного порядка вычисления, приводя к чтению неинициализированных данных.
История
При портировании кода на другой компилятор разница в реализации порядка вычисления операндов привела к тем, что цикл типа while (arr[i++] && i < MAX && arr[++i]) стал вести себя непредсказуемо. Баг нашли только по результатам фазы тестирования уже на устройстве клиента.