Floating point exceptions - gcc error?

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 non-zero value corresponding to FE_DIVBYZERO , but it prints 0. Changing the second line from main to double x = 1.0/0.0; gives the expected behavior. Is this allowed, or is it a mistake?

Edit: For what it's worth, at first it might seem that in most real codes, operations that may cause fenv exceptions cannot be optimized, so it would be safe to do large calculations and check at the end if an overflow occurred, div zero etc. However, things get messy, and the real problem arises when you consider investing and optimizing. If such a function is embedded in a situation where it will always be divided by zero due to constant arguments, gcc can become really smart and optimize the entire built-in function essentially until return INFINITY; without any exceptions.

+4
source share
5 answers

This is the expected behavior. gcc does not evaluate the expression, because after that it will have nothing to do with it.

If you compile with -Wall, it warns you that the statement is not valid and that it ignores the pragma statement.

GCC is not fully compatible with C99. For more information see http://gcc.gnu.org/c99status.html

To solve this problem see: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20785

+6
source

This is a bit of a gray area. Strictly reading the standard floating-point environment can easily make you think this is a mistake. I suspect GCC proponents will disagree with this reading.

In this regard, I'm not sure that the GCC even claims to understand the pragma FENV_ACCESS. Of course, earlier versions did not.

+2
source

Compiling from -Wall to gcc 4.6.0 says:

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

According to the GCC 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". 

Unfortunately, -frounding-math does not seem to affect your program.

Perhaps a compiler error; I would ask on one of the GCC mailing lists.

+2
source

Your compiler may have optimized the original version. Recognizing that two constants are not β€œused” in any non-trivial sense, it may not even exist in a compiled binary.

The second example modifies this by actually assigning the operation to a variable.

0
source

I think the expression will be optimized in the first case, but not in the second. I can reproduce your results with gcc 4.2 using gcc -O0 , but if I go to gcc -O3 then I get 0 in both cases.

0
source

All Articles