У меня есть программа, которая почти сразу же заканчивается на -O0
на gcc, но навсегда зависает с gcc и -O3
Да, потому что программа компилируется до бесконечностицикл при включенной оптимизации.
Это ошибка компилятора?Отсутствие документации для правильных предостережений для использования [[gnu::pure]]
?Неправильное прочтение документации для [[gnu::pure]]
такое, что я кодировал ошибку?
Это не ошибка компилятора.get_value_plus
не является pure
функцией:
[[gnu::pure]] int get_value_plus(int x)
{
return val.load() + x;
}
, поскольку возвращаемое значение может измениться в любое время (для того же x
), поскольку ожидается, что val
будет изменен другимthread.
Однако компилятор, полагая, что get_value_plus
всегда будет возвращать одно и то же значение, выполнит CSE и, следовательно, примет следующее:
while ((get_value_plus(5) + get_value_plus(5)) % 2 == 0);
canзаписать как:
int x = get_value_plus(5);
while ((x + x) % 2 == 0);
Что, действительно, представляет собой бесконечный цикл независимо от значения x
:
while (true);
Пожалуйста, см. GCCдокументация по pure
для получения более подробной информации.
В общем, избегайте использования подсказок по оптимизации, если они не совсем понятны!
В этом случае недоразумение заключается в том, что функции pure
разрешено чтение глобальной памяти, но только если эта память изменяется от вызова к вызову кем-то, кроме вызывающей стороны:
Однако функции, объявленные с атрибутом pure, могут безопасно читать любые энергонезависимые объекты,и изменить значение объектов таким образом,это не влияет на их возвращаемое значение или наблюдаемое состояние программы.