Status of __STDC_IEC_559__ with modern C compilers

c, clang, floating-point, gcc, ieee-754

Solution

I believe `__STDC_IEC_559__` relies on some library features and can't be defined solely by the compiler. See this post for some information. This is not uncommon for C -- the compiler and the C library must sometimes cooperate in order to implement the entire standard.

What you're asking depends on the compiler. I think you would have to have special knowledge of the compiler in order to decide this. In the specific case of GCC, it defines a macro to tell you. Search this node of the manual for `__GCC_IEC_559`.

Well... I don't know the answer to this one :-). The original post seems to indicate that, yes, GCC might define `__GCC_IEC_559` if it intends to implement IEEE 754, even if it does not actually do so.

Problem

C99 added a macro `__STDC_IEC_559__` which can be used to test if a compiler and standard library conform to the ISO/IEC/IEEE 60559 (or IEEE 754) standard. According to the answers for this question how-to-check-that-ieee-754-single-precision-32-bit-floating-point-representation most C compilers don't set the preprocessor macro `__STDC_IEC_559__`. According to GCC's documentation it does not define `__STDC_IEC_559__`. I tested this with GCC 4.9.2 and Clang 3.6.0 both using with `glibc` 2.21 using the following code. ``` //test.c //#include <features.h> int main(void) { #if defined ( __STDC_IEC_559__ ) //#if defined ( __GCC_IEC_559__ ) return 1; #else return 0; #endif } ``` and then ``` echo $? ``` This shows that with this code `__STDC_IEC_559__` is defined with GCC but not with Clang. I then did `gcc -E` and it showed that the file `stdc-predef.h` is included. This file defines `__STDC_IEC_559__`. ``` /* glibc's intent is to support the IEC 559 math functionality, real and complex. If the GCC (4.9 and later) predefined macros specifying compiler intent are available, use them to determine whether the overall intent is to support these features; otherwise, presume an older compiler has intent to support these features and define these macros by default. */ #ifdef __GCC_IEC_559 # if __GCC_IEC_559 > 0 # define __STDC_IEC_559__ 1 # endif #else # define __STDC_IEC_559__ 1 #endif ``` This confirms that it's `glibc` that defines this macro and not GCC. However, when I include `features.h` (or `stdio.h`) this file is included by Clang as well and that `__STDC_IEC_559__` is defined. So `__STDC_IEC_559__` is defined by both GCC and Clang (with a `glibc` header file) which seems to disagree with the answer to the first question I linked to. I then tested `musl` (e.g. `musl-gcc -test.c`) which is a different standard library than `glibc`. This showed that `__STDC_IEC_559__` is not defined with `musl`. As I understand it the standard C library does not define the basic floating point algebra. For example the standard C library does not define the result of `1.0/-0.0`. This is defined by the compiler. My questions are (ranked in order of importance to me): - Why is `__STDC_IEC_559__` defined by `glibc` and not by the compiler? - If I made my own standard library and I wanted to define `__STDC_IEC_559__` I would need to know that the compiler already conforms to IEEE 754 for operations not defined in my standard library (e.g `1.0/-0.0`). Is there documentations for this or a macro to test for this? - Wikipedia states that "users should be aware that this macro (`__STDC_IEC_559__`) is sometimes defined while it shouldn't be". Is this statement still accurate?

Original source

Related problems