浮点exception – gcc bug?

请考虑以下代码:

#include  #include  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?

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

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

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

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

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

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

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

在gcc 4.6.0上用-Wall编译说:

 fc:5:0: warning: ignoring #pragma FENV_ACCESS ON [-Wunknown-pragmas] 

根据GCC信息页面 :

 * `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邮件列表。

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

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

我认为表达式在第一种情况下会被优化掉,但在第二种情况下则不会。 我可以用gcc 4.2和gcc -O0重现你的结果,但是如果我去gcc -O3那么我在两种情况下都得到0。