Статус __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, Это определяется компилятором.

Мои вопросы (ранжированы в порядке важности для меня):

  1. Почему __STDC_IEC_559__ определяется glibc а не компилятором?
  2. Если бы я сделал свою собственную стандартную библиотеку, и я хотел бы определить __STDC_IEC_559__ Мне нужно знать, что компилятор уже соответствует IEEE 754 для операций, не определенных в моей стандартной библиотеке (например, 1.0/-0.0). Есть ли документация для этого или макрос для проверки этого?
  3. Википедия утверждает, что "пользователи должны знать, что этот макрос (__STDC_IEC_559__) иногда определяется, хотя не должно быть ". Является ли это утверждение все еще точным?

1 ответ

  1. я верю __STDC_IEC_559__ опирается на некоторые библиотечные функции и не может быть определена только компилятором. Смотрите этот пост для получения дополнительной информации. Это не редкость для C - компилятор и библиотека C иногда должны взаимодействовать, чтобы реализовать весь стандарт.

  2. То, что вы спрашиваете, зависит от компилятора. Я думаю, что вы должны иметь специальные знания компилятора, чтобы решить это. В конкретном случае GCC, он определяет макрос, чтобы сообщить вам. Искать этот узел руководства для __GCC_IEC_559,

  3. Ну... я не знаю ответ на этот вопрос:-). Оригинальный пост, кажется, указывает, что да, GCC может определить __GCC_IEC_559 если он намеревается реализовать IEEE 754, даже если он на самом деле этого не делает.

Другие вопросы по тегам