В C99 добавлен макрос __STDC_IEC_559__
, который может использоваться для проверки соответствия стандартного и стандартного библиотек стандарту ISO/IEC/IEEE 60559 (или IEEE 754).
В соответствии с ответами на этот вопрос
how-to-check-that-ieee-754-single-precision-32-bit-floating-point-presentation большинство компиляторов C не устанавливают макрос препроцессора __STDC_IEC_559__
.
В соответствии с документацией GCC он не определяет __STDC_IEC_559__
.
Я тестировал это с помощью GCC 4.9.2 и Clang 3.6.0, используя как glibc
2.21, используя следующий код.
//test.c
//#include <features.h>
int main(void) {
#if defined ( __STDC_IEC_559__ )
//#if defined ( __GCC_IEC_559__ )
return 1;
#else
return 0;
#endif
}
а затем
echo $?
Это показывает, что с этим кодом __STDC_IEC_559__
определяется с помощью GCC, но не с Clang. Затем я сделал gcc -E
, и он показал, что файл stdc-predef.h
включен. Этот файл определяет __STDC_IEC_559__
.
/* glibc 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
Это подтверждает, что он glibc
определяет этот макрос, а не GCC.
Однако, когда я включаю features.h
(или stdio.h
), этот файл также входит в состав Clang и что __STDC_IEC_559__
определяется.
So __STDC_IEC_559__
определяется как GCC, так и Clang (с заголовком glibc
), который, похоже, не согласен с ответом на первый вопрос, с которым я связан.
Затем я протестировал musl
(например, musl-gcc -test.c
), который является другой стандартной библиотекой, чем glibc
. Это показало, что __STDC_IEC_559__
не определяется с помощью musl
.
Как я понимаю, стандартная библиотека C не определяет основную алгебру с плавающей запятой. Например, стандартная библиотека C не определяет результат 1.0/-0.0
. Это определяется компилятором.
Мои вопросы (оцениваются в порядке важности для меня):
- Почему
__STDC_IEC_559__
определяетсяglibc
, а не компилятором? - Если бы я создал свою собственную стандартную библиотеку, и я хотел бы определить
__STDC_IEC_559__
, мне нужно было бы знать, что компилятор уже соответствует IEEE 754 для операций, не определенных в моей стандартной библиотеке (например,1.0/-0.0
). Есть ли документы для этого или макроса для проверки на это? - Википедия заявляет, что "пользователи должны знать, что этот макрос (
__STDC_IEC_559__
) иногда определяется, пока он не должен быть". Является ли это утверждение еще точным?