C++ 优化器可以假定浮点不是NaN吗?

C++ 优化器可以假定浮点不是NaN吗?,c++,language-lawyer,C++,Language Lawyer,编译器可以做出一些可能导致未定义行为的假设(例如假设加法不会溢出)。他们是否可以对浮点NaN作出这样的假设 例如: double a = some_calc(); double b = a; if( a == b ) do_something(); 优化器能否删除条件语句并假设它始终为真?或者,它是否绑定到平台浮点规则(IEEE),并在值为NaN时强制执行检查 也就是说,编译器能否基于double不包含NaN的假设进行优化?由于C++标准没有说明浮点在平台上的实际运行,所以我不清楚这是否完

编译器可以做出一些可能导致未定义行为的假设(例如假设加法不会溢出)。他们是否可以对浮点NaN作出这样的假设

例如:

double a = some_calc();
double b = a;
if( a == b )
  do_something();
优化器能否删除条件语句并假设它始终为真?或者,它是否绑定到平台浮点规则(IEEE),并在值为NaN时强制执行检查

也就是说,编译器能否基于double不包含NaN的假设进行优化?由于C++标准没有说明浮点在平台上的实际运行,所以我不清楚这是否完全被指定。 或者它是否受平台浮点规则(IEEE)的约束

不一定,如果实现使用IEEE 754浮点数,
std::numeric\u limits::is\u iec559
设置为true

如果值为NaN,则强制执行检查


如果实现确实使用IEEE 754,则算术运算的结果必须符合IEEE浮点规则,但就比较而言,可以对其进行优化。如果编译器在同一翻译单元中(或在链接时代码生成过程中)可以分析
某些计算的主体,并且可以得出结论,它永远不会返回NaN(即返回一个常量),则可以对其进行优化,因为代码的语义不会改变。

如果实现文档本身支持NaN,然后它必须支持南部。优化器是实现的一部分。这些信息够了吗?;-)也就是说,实现能否定义这样的NaN以允许上述优化。标准确实有<代码> iSnA< /Cuff>函数,所以不会有功能丧失。我不认为C++标准要求<代码>NaN
,其中,
NaN
是一个安静的NaN。如果我是对的,那么C++实现可以定义它自己的NO-A数,使得<代码> n==nA/c>,然后优化是有效的。该实现不支持IEEE NAN。如果我错了,它是C++所要求的<代码>NaN,那么优化器就不能像对待
运算符==(double,double)
那样对待
运算符==(int,int)
。因此,决定将取决于编译器是否能够确定
某些计算是否可以返回NaN。如果它不能100%确定地知道,它将不得不进行比较(或者进行nan检查,看是否更快)。@edA-qamort-ora-y,是的,这适用于所有优化。如果函数体对编译器来说是不透明的,它就不能假设任何东西(函数可以返回任何值,也有副作用),但是,有些编译器有优化器标志,用户可以告诉他们,“我不在乎NaNs。”有了这样的标志,编译器就会忽略NaNs的可能性。@SebastianRedl,嗯,一些编译器还可以忽略准确再现IEEE语义的标志,因此有如下内容:)