Status of __STDC_IEC_559__ with modern C compilers

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):

  1. Why is __STDC_IEC_559__ defined by glibc and not by the compiler?
  2. 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?
  3. 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?

Solution 1:

  1. 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.

  2. 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.

  3. 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.