Статус __STDC_IEC_559__ с современными компиляторами Си
C99 добавил макрос __STDC_IEC_559__
который можно использовать для проверки соответствия компилятора и стандартной библиотеки стандарту ISO/IEC/IEEE 60559 (или IEEE 754).
По ответам на этот вопрос
как это проверить ieee-754-одинарная точность-32-битное представление с плавающей точкой большинство компиляторов 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'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
Это подтверждает, что это glibc
который определяет этот макрос, а не GCC.
Тем не менее, когда я включаю features.h
(или же stdio.h
) этот файл также включен Clang и что __STDC_IEC_559__
определено.
Так __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__
) иногда определяется, хотя не должно быть ". Является ли это утверждение все еще точным?
1 ответ
я верю
__STDC_IEC_559__
опирается на некоторые библиотечные функции и не может быть определена только компилятором. Смотрите этот пост для получения дополнительной информации. Это не редкость для C - компилятор и библиотека C иногда должны взаимодействовать, чтобы реализовать весь стандарт.То, что вы спрашиваете, зависит от компилятора. Я думаю, что вы должны иметь специальные знания компилятора, чтобы решить это. В конкретном случае GCC, он определяет макрос, чтобы сообщить вам. Искать этот узел руководства для
__GCC_IEC_559
,Ну... я не знаю ответ на этот вопрос:-). Оригинальный пост, кажется, указывает, что да, GCC может определить
__GCC_IEC_559
если он намеревается реализовать IEEE 754, даже если он на самом деле этого не делает.