Порядок оценки назначения (Нашел ли я свою первую ошибку компилятора?)

StackOverflow https://stackoverflow.com/questions/2370907

  •  24-09-2019
  •  | 
  •  

Вопрос

В этом коде есть интересная ошибка:

родовое слово

Для большинства компиляторов приведенный выше код приводит к установке поля «значение» всех структур в соответствующих массивах на 1. Однако для одного конкретного компилятора (назовем его xcc) структуры в struct_array1 НЕ инициализируются правильно.В поле «значение» для всех структур установлено значение 0, что меня немного удивило.

Следующий фрагмент кода работает должным образом на всех компиляторах:

родовое слово

Я полностью отключился, или компилятор "xcc" просто отображает ошибку?

Я не могу найти ничего, что отображало бы поведение, зависящее от реализации, в первом фрагменте кода;насколько я понимаю, приращение постфикса должно иметь приоритет над присваиваниями, а присваивания следует оценивать справа налево.В первом фрагменте кода не должно быть ничего странного, за исключением того, что он немного нечитаем.

Это было полезно?

Решение

Вы активировали неопределенное поведение, потому что оно изменяет код i, а также извлекает его значение с целью, отличной от вычисления нового значения, без промежуточной точки последовательности.

Соответствующая часть стандарта C99 - это пункт раздела 6.5:

<цитата>

Между предыдущей и следующей последовательностью точка объект должен хранить значение, измененное не более одного раза оценка выражения. Кроме того, предыдущая стоимость должна быть только чтение, чтобы определить значение, которое будет хранится.

Другие советы

struct_array1[i].value = struct_array2[i++].value = 1

Я думаю, что это поведение undefined, потому что i++ не гарантирует выполнение всех своих побочных эффектов до тех пор, пока не будет достигнута следующая точка последовательности.Следующая точка последовательности - это «воображаемый» код генерирующего кода в конце оператора.Это распространенная ошибка, я думаю, вы можете найти много тем по SO, относящихся к этому, просто ищите точки последовательности.

На самом деле мы не предполагаем выполнять более одного вычисления для одной и той же переменной в signle

выражение.Если мы это сделаем, это будет неопределенное поведение.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top