浮点异常 - gcc bug?

时间:2011-06-13 21:47:47

标签: c gcc floating-point standards fenv

请考虑以下代码:

#include <fenv.h>
#include <stdio.h>
int main()
{
    #pragma STDC FENV_ACCESS ON
    1.0/0.0;
    printf("%x\n", fetestexcept(FE_ALL_EXCEPT));
}

我希望它打印一个与FE_DIVBYZERO对应的非零值,但会打印0.将main的第二行更改为double x = 1.0/0.0;会产生预期的行为。这是允许的,还是一个bug?

编辑:对于它的价值,起初似乎在大多数现实世界的代码中,可能导致引发fenv异常的操作无法优化,因此可以安全地执行大型计算并在结束时检查是否发生了溢出,被零除等。但是,当您考虑内联和优化时,事情会变得混乱,并且会出现真正的问题。如果这样的函数在由于常量参数总是最终除以零的情况下被内联,gcc可能会非常智能并且基本上优化整个内联函数return INFINITY;而不提高任何例外。

5 个答案:

答案 0 :(得分:6)

这是预期的行为。 gcc不会对表达式求值,因为之后它与它无关。

如果使用“-Wall”进行编译,它会警告您该语句无效,并且它会忽略该pragma语句。

GCC不完全符合C99标准。有关更多信息,请参阅: http://gcc.gnu.org/c99status.html

有关实施此行为的问题,请参阅:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20785

答案 1 :(得分:2)

这是一个灰色地带。严格阅读标准的浮点环境部分很容易让人相信这是一个错误。但我怀疑GCC维护者不同意这种阅读。

就此而言,我不确定GCC是否声称理解FENV_ACCESS编译指示。当然早期的版本没有。

答案 2 :(得分:2)

在gcc 4.6.0上使用-Wall进行编译说:

f.c:5:0: warning: ignoring #pragma FENV_ACCESS ON [-Wunknown-pragmas]

根据GCC info pages

* `The default state for the `FENV_ACCESS' pragma (C99 7.6.1).'

 This pragma is not implemented, but the default is to "off" unless
 `-frounding-math' is used in which case it is "on".

不幸的是,-frounding-math似乎对您的计划没有任何影响。

可以说是编译器错误;我会问其中一个GCC邮件列表。

答案 3 :(得分:0)

您的编译器可能已优化原始版本。认识到这两个常量在任何非平凡的意义上都没有被“使用”,它甚至可能不存在于已编译的二进制文件中。

第二个例子通过将操作实际分配给变量来改变它。

答案 4 :(得分:0)

我认为表达式在第一种情况下被优化掉了,但在第二种情况下却没有。我可以使用gcc 4.2和gcc -O0重现您的搜索结果,但是如果我转到gcc -O3那么我在两种情况下都会得到0。