为什么-ffast-math选项打破了我的bool条件

时间:2015-12-03 02:55:37

标签: c++ boolean fast-math

这是导致问题的程序的关键部分,程序是完全顺序的。

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;

使用-ffast-math选项,我得到了打印输出&#34; 0 0 5&#34;

没有选项-ffast-math,我得到了打印输出&#34; 0 0 NAN&#34;

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

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;

使用-ffast-math选项,我得到了&#34; 0 0 NAN&#34;

比我将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;

使用-ffast-math选项,我得到了&#34; 0 0 -5&#34;

我知道-ffast-math打破了IEEE标准,并且它不会检查NAN,但究竟是什么原因打破了上述简单的条件检查?

1 个答案:

答案 0 :(得分:3)

-ffast-math指示g ++假设NaN永远不会发生。因此,将某些东西设置为NaN是未定义行为的粗略等价物,因为编译器可以安全地假设它永远不会发生。有关编译器如何消除它所知道的分支的信息,请参阅this系列LLVM博客文章。无法执行,以及如何令人惊讶。

简短版本:g ++进入&#34;我们处于快速数学模式,因此dbl_num_永远不会设置为NaN,所以从不采用else分支,所以exists_必须为true,所以我可以优化除了那条道路以外的一切&#34;。

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