gcc -Ofast - 完整的限制列表

jav*_*red 5 c++ gcc fast-math

-Ofast在我的程序中使用gcc选项导致延迟要求.我写了简单的测试程序:

#include <iostream>
#include <math.h>

static double quiet_NaN = std::numeric_limits<double>::quiet_NaN();

int main()
{
    double newValue = 130000; 
    double curValue = quiet_NaN; 
    printf("newValue = %f\n", newValue); 
    printf("curValue = %f\n", curValue); 
    printf("isnan(newValue) = %d\n", isnan(newValue)); 
    printf("isnan(curValue) = %d\n", isnan(curValue)); 
    printf("newValue == curValue %d\n", (newValue == curValue)); 
    printf("newValue != curValue %d\n", (newValue != curValue)); 
}
Run Code Online (Sandbox Code Playgroud)

我试图用默认标志和-Ofast运行它:

$ g++ TestPointer.cpp 
$./a.out 
newValue = 130000.000000
curValue = nan
isnan(newValue) = 0
isnan(curValue) = 1
newValue == curValue 0
newValue != curValue 1

$ g++ -Ofast TestPointer.cpp 
$ ./a.out 
newValue = 130000.000000
curValue = nan
isnan(newValue) = 0
isnan(curValue) = 1
newValue == curValue 1
newValue != curValue 0
Run Code Online (Sandbox Code Playgroud)

所以结果!===不可信任.这是否意味着我应该==并且!=只有当两个值都知道不是nan时,否则我应该先测试isnan

是否保证isnan正常使用-Ofast?如何正确==!=双重工作-Ofast?有人可以提供完整的限制列表-Ofast吗?

Pra*_*tic 9

你正在观察的影响-ffast-math.

来自文档:

-Ofast

无视严格的标准合规性.-Ofast启用所有-O3优化.它还支持对所有符合标准的程序无效的优化.它打开-ffast-math和Fortran特定的-fno-protect-parens和-fstack-arrays.

-ffast,数学

设置-fno-math-errno,-funsafe-math-optimizations,-fno-trapping-math,-ffinite-math-only,-fno-rounding-math,-fno-signaling-nans和fcx-limited-range.

-ffinite,数学只

允许优化浮点运算,假设参数和结果不是NaN或+ -Infs.

这个标记为无效的gcc bug报告有几个.

-ffast-math和isnan的问题

此外,严格的IEEE浮点数的比较总是导致错误.

检查C++中的double(或float)是否为NaN

这不一定适用,-ffast-math但它解释了你所展示的内容.

gcc没有描述-ffast-math浮点数如何工作的正式标准,所以如果你必须假定gcc版本之间的一致性,那么你只需要凭经验计算出细节.更重要的是,完全避免的组合NaN-ffast-math.