Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

Предупреждения о непоследовательных изменениях переменной

#cpp #cpp17


int main() {
    int x{};
    x = x++;
}


Почему эта программа выдаёт следующие предупреждения в gcc и clang (1 и 2)?


  gcc - warning: operation on x may be undefined 
  
  clang - warning: multiple unsequenced modifications to x

    


Ответы

Ответ 1



Потому что ни GCC, ни Clang на сегодняшний день еще не реализовали поддержку современных свойств ядра языка (core language) С++17 и/или не привели в соответствие с ними свою систему диагностических сообщений. Этот код имеет вполне определенное поведение в C++17, но не в C++14. В С++14 и ранее побочный эффект оператора присваивания (занесение в x значения 0) и побочный эффект оператора ++ (занесение в x значения 1) никак не упорядочены между собой. Формально поведение не определено, а практически эти эффекты могут произойти в любом порядке, т.е. финальное значение x может оказаться как 0 так и 1. С++17 ввел требование полного упорядочения в операторе присваивания: правый операнд (вместе со всеми своими побочным эффектами) упорядочен перед левым, а побочный эффект всего присваивания упорядочен после вычисления обоих операндов. Т.е. x должен однозначно получать значение 0. Это требование еще не реализовано в вышеупомянутых компиляторах. В данном случае оба компилятора "попадают" в правильное значение, несмотря на предупреждения. Но в более хитрых примерах поведение может быть неправильным. Например, вот такая наивная попытка "обмена байтов" unsigned x = 0xaabb; ((x ^= (x >> 8)) ^= ((x & 0xFF) << 8)) ^= (x >> 8); std::cout << std::hex << x << std::endl; не должна обменивать байты. Правильный результат - 0x11bb в x. Clang "попадает" и в него, а вот в GCC x получает значение 0xbbaa, что неправильно.

Комментариев нет:

Отправить комментарий