Я читал C Traps and Pitfalls и читал, что следующий код может работать в некоторых реализациях и не работать в других из-за неопределенного порядка = и ++. Это все еще верно для C?
int i = 0; while (i < n) y[i] = x[i++];
Если это так, это действительно невероятно.
Ничего невероятного.Довольно определенное неопределенное поведение.Узнайте больше о точках последовательности .Просто писать как:
int i = 0; while (i < n) { y[i] = x[i]; i++; }
безопаснее и удобочитаемее.
Постфикс ++ имеет результат и побочный эффект . Результатом является текущее значение операнда. Побочный эффект заключается в том, что операнд увеличивается на единицу. Проблема заключается в том, что побочный эффект не нужно применять сразу после вычисления выражения; это должно только быть применено перед следующей точкой последовательности.
++
Из стандарта языка C ( n1256 ):
6,5 выражений ... 2 Между предыдущей и следующей точкой последовательности объект должен иметь свое сохраненное значение модифицируется не более одного раза путем вычисления выражения. 72) Кроме того, предыдущее значение должен быть прочитан только для определения значения, которое будет сохранено. 73) ... 72) Флаг состояния с плавающей точкой не является объектом и может быть установлен более одного раза в выражении. 73) Этот параграф отображает неопределенные выражения оператора, такие как i = ++i + 1; a[i++] = i; позволяя i = i + 1; a[i] = i;
i = ++i + 1; a[i++] = i;
i = i + 1; a[i] = i;
Не особенно удивительно, что этот код имеет неопределенное поведение, потому что он семантически неоднозначен: в y[i], какое значение i предназначено?Значение до приращения или после?(Имейте в виду, что оператор = не указывает, что одна сторона оценивается раньше другой)
y[i]
i
=
Ну, i ++ означает «увеличить i после использования его значения», так что я думаю, что это правильно (ну, я изменил идею, читая другие посты) Скорее я бы сделал:
while((i++) < n) y[i] = x[i];
Да, это все еще UB.
§ 1.9p7 В определенных точках последовательности выполнения, называемых точками последовательности, все побочные эффекты предыдущих оценок должны быть завершены, и никаких побочных эффектов последующих оценок не должно быть.(§1.9 / 7)