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 byglibc
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.g1.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?
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.
来源:https://stackoverflow.com/questions/31181897/status-of-stdc-iec-559-with-modern-c-compilers