为什么-fast数学选项打破了我的bool条件

why -ffast-math option break my bool condition

本文关键字:我的 bool 条件 -fast 选项 为什么      更新时间:2023-10-16

这是导致问题的程序的关键部分,并且程序是完全连续的。

exist_bool类私有成员,dbl_num_double类私有成员

exist_ = false;
dbl_num_ = 0;
std::cout << dbl_num_ << " " ;
if(exist_ == true)
{
  dbl_num_ = 5;
}else
{
  dbl_num_ = NAN;
}
std::cout << exist_ << " " << dbl_num_ << std::endl;

有了选项-fast数学,我得到了打印输出"0 0 5"

没有选项-fast maths,我得到了打印输出的"0 0 NAN"

此外,如果我将程序更改为

exist_ = false;
dbl_num_ = 0;
std::cout << dbl_num_ << " " ;
if(exist_ == true)
{
  std::cout << exist_ << " " ;
  dbl_num_ = 5;
}else
{
  dbl_num_ = NAN;
}
std::cout << exist_ << " " << dbl_num_ << std::endl;

通过选项-fast数学,我得到了"0 NAN"

然后我将NAN改为-5

exist_ = false;
dbl_num_ = 0;
std::cout << dbl_num_ << " " ;
if(exist_ == true)
{
  dbl_num_ = 5;
}else
{
  dbl_num_ = -5;
}
std::cout << exist_ << " " << dbl_num_ << std::endl;

通过选项-fast数学,我得到了"0 0-5"

我知道-fast数学违反了IEEE标准,它不检查NAN,但它违反上述简单条件检查的确切原因是什么?

-fast math指示g++假设NaN从未发生。因此,将某个东西设置为NaN大致相当于未定义的行为,因为编译器可以安全地假设它从未发生过。请参阅这一系列LLVM博客文章,了解编译器如何消除它"知道"无法执行的分支,以及这是如何令人惊讶的。

简短的版本:g++说:"我们处于快速数学模式,所以dbl_num_从未设置为NaN,所以else分支从未被采用,所以exist_必须为true,所以我可以优化除该路径之外的所有内容"。

编辑:另请参阅此gcc错误报告。