Я недостаточно знаком с FPU, чтобы комментировать с уверенностью, но я предполагаю, что компилятор позволяет существующему значению, которое, по его мнению, должно равняться x
, сидеть в этом сравнении. Возможно, вы идете y = x + 20.; y = y - 20;
y
уже в стеке FP, поэтому вместо загрузки x
компилятор просто сравнивает с y
. Но из-за ошибок округления, y
не совсем 0.0
, как это должно быть, и вы получите странные результаты, которые вы видите.
Для лучшего объяснения: Почему cos (x)! = Cos (y), хотя x == y? из C ++ FAQ lite. Это часть того, что я пытаюсь донести до меня, я просто не мог вспомнить, где именно я это прочитал до сих пор.
Изменение константной ссылки исправляет это, потому что компилятор беспокоится о псевдонимах. Он вызывает загрузку с x
, потому что не может предположить, что его значение не изменилось в какой-то момент после создания y
, и поскольку x
на самом деле точно 0.0
[, который представлен в каждом формате с плавающей запятой, который я я знаком с] ошибки округления исчезают.
Я почти уверен, что MS предоставляет прагму, которая позволяет вам устанавливать флаги FP для каждой функции. Или вы можете переместить эту процедуру в отдельный файл и присвоить этому файлу настраиваемые флаги. В любом случае, это может предотвратить страдания всей вашей программы, просто чтобы эта рутина была счастлива.