Предупреждение CppCheck: выражение зависит от порядка вычисления x = x |= (1 ‹‹ 3)

Строка кода на C

x = x |= (1 << 3);

который дает ошибку cppCheck: «Выражение« x = x | = 1 »зависит от порядка оценки побочных эффектов»

тогда как линия

x |= (1 << 3);

is ok.

я думал

x = x |= (1 << 3);

будет таким же, как

x = x = x | (1 << 3);

что просто

x = (x = (x | (1 << 3)));

где на самом деле внешнее присвоение x не имеет никакого эффекта, то есть результат такой же, как и

x |= (1 << 3);

Так на что именно жалуется CppCheck?

редактировать: думаю, что это дубликат того, почему j = j++ является или не совпадает с j++, который обсуждается в вопросе, упомянутом выше.


person floquet22    schedule 15.02.2016    source источник
comment
Вы можете прочитать об точках последовательности. Двойное изменение переменной в одной точке секвенции — это поведение undefined.   -  person Cornstalks    schedule 15.02.2016
comment
Возможный дубликат Почему эти конструкции (с использованием ++) имеют неопределенное поведение?   -  person too honest for this site    schedule 15.02.2016


Ответы (1)


Эта цитата из ссылки на точки последовательности @Cornstalks очень хорошо объясняет это.

Выражения... которые дважды изменяют одно и то же значение - это мерзость, которую не нужно разрешать (или, во всяком случае, не нужно четко определять, т. е. нам не нужно придумывать способ сказать, что они делают, и компиляторы не обязаны их поддерживать).

Стандарт C просто ничего не предписывает об этих типах выражений, и поэтому не существует определенного порядка вычислений, гарантированного во всех средах.

довольно быстрое и простое объяснение:

x = x |= 1 в значительной степени эквивалентен x = x += 1 с точки зрения побочных эффектов (модификаций x). x = x += 1 эквивалентно x = ++x в C. Это выражение является хорошо известным неопределенным выражением.

Подробнее об этом читайте [здесь]

person cozyconemotel    schedule 15.02.2016
comment
В соответствии со стандартом C Побочный эффект обновления сохраненного значения левого операнда упорядочивается после вычисления значения левого и правого операндов. И 3 Если значение, хранящееся в объекте, считывается из другого объекта, который перекрывается способ хранения первого объекта, то перекрытие должно быть точным, и два объекта должны иметь квалифицированные или неквалифицированные версии совместимого типа; в противном случае поведение не определено. Таким образом, это выражение корректно определено. - person Vlad from Moscow; 15.02.2016
comment
@Vlad Да, побочные эффекты упорядочиваются после вычислений. Однако в стандарте C также указано, что между предыдущей и следующей точкой последовательности сохраненное значение скалярного объекта должно быть изменено не более одного раза путем вычисления выражения. В этом выражении есть два побочных эффекта для x. Ваша вторая цитата совершенно неуместна, на мой взгляд. - person cozyconemotel; 15.02.2016