简体   繁体   English

浮点异常 - gcc 错误?

[英]Floating point exceptions - gcc bug?

Consider the following code:考虑以下代码:

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

I would expect it to print a nonzero value corresponding to FE_DIVBYZERO , but it prints 0. Changing the second line of main to double x = 1.0/0.0;我希望它打印一个对应于FE_DIVBYZERO的非零值,但它打印 0。将main的第二行更改为double x = 1.0/0.0; gives the expected behavior.给出预期的行为。 Is this permitted, or is it a bug?这是允许的,还是一个错误?

Edit: For what it's worth, at first it may seem that in most real-world code, the operations which might cause fenv exceptions to be raised could not be optimized out, so one could safely perform large computations and check at the end whether any overflow, div-by-zero, etc. happened.编辑:对于它的价值,起初似乎在大多数现实世界的代码中,可能导致 fenv 异常的操作无法被优化出来,因此人们可以安全地执行大型计算并在最后检查是否有发生溢出、除零等。 However, things get messy and a real issue emerges when you consider inlining and optimization.然而,当你考虑内联和优化时,事情变得一团糟,一个真正的问题出现了。 If such a function got inlined in a situation where it would always end up dividing by zero due to constant arguments, gcc might get really smart and optimize the whole inlined function essentially to return INFINITY; If such a function got inlined in a situation where it would always end up dividing by zero due to constant arguments, gcc might get really smart and optimize the whole inlined function essentially to return INFINITY; without raising any exceptions.不引发任何异常。

This is expected behaviour.这是预期的行为。 gcc doesn't evaluate the expression, because it would have nothing to do with it afterwards. gcc 不计算表达式,因为之后它与它无关。

If you compile with "-Wall", it warns you that the statement has no effect, and that it ignores the pragma statement.如果您使用“-Wall”进行编译,它会警告您该语句无效,并且它会忽略 pragma 语句。

GCC is not fully C99 compliant. GCC 不完全符合 C99。 For more information, see: http://gcc.gnu.org/c99status.html更多信息参见: http://gcc.gnu.org/c99status.html

For the issue of implementing this behaviour, see: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20785有关实现此行为的问题,请参阅: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20785

This is something of a gray area.这是一个灰色地带。 A strict reading of the floating-point environment section of the standard could easily lead one to believe that this is a bug.严格阅读标准的浮点环境部分很容易让人相信这是一个错误。 I suspect that the GCC maintainers will disagree with that reading, however.然而,我怀疑 GCC 的维护者会不同意这种解读。

For that matter, I'm not sure that GCC even claims to understand the FENV_ACCESS pragma.就此而言,我不确定 GCC 甚至声称了解 FENV_ACCESS 杂注。 Certainly earlier versions did not.当然早期版本没有。

Compiling with -Wall on gcc 4.6.0 says:在 gcc 4.6.0 上使用-Wall编译说:

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

According to the GCC info pages :根据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".

Unfortuantely, -frounding-math does not seem to have any effect on your program.不幸的是, -frounding-math似乎对您的程序没有任何影响。

Arguably a compiler bug;可以说是编译器错误; I would ask on one of the GCC mailing lists.我会在 GCC 邮件列表之一上询问。

It's possible that your compiler has optimized the original version out.您的编译器可能已经优化了原始版本。 Recognizing that the two constants are not "used" in any non-trivial sense, it may not even exist in the compiled binary.认识到这两个常量在任何重要的意义上都没有“使用”,它甚至可能不存在于编译的二进制文件中。

The second example changes that, by actually assigning the operation to a variable.第二个示例通过将操作实际分配给变量来改变这一点。

I think the expression is getting optimised away in the first case, but not in the second.我认为表达式在第一种情况下得到优化,但不是在第二种情况下。 I can reproduce your results with gcc 4.2 with gcc -O0 , but if I go to gcc -O3 then I get 0 in both cases. I can reproduce your results with gcc 4.2 with gcc -O0 , but if I go to gcc -O3 then I get 0 in both cases.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM