__STDC_IEC_559__与现代C编译器的状态

时间:2015-07-02 10:18:45

标签: c gcc floating-point clang ieee-754

C99添加了一个宏__STDC_IEC_559__,可用于测试编译器和标准库是否符合ISO / IEC / IEEE 60559(或IEEE 754)标准。

根据这个问题的答案
how-to-check-that-ieee-754-single-precision-32-bit-floating-point-representation大多数C编译器都没有设置预处理器宏__STDC_IEC_559__

According to GCC's documentation它没有定义__STDC_IEC_559__

我使用以下代码使用glibc 2.21对GCC 4.9.2和Clang 3.6.0进行了测试。

//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. Wikipedia states that“用户应该知道这个宏(__STDC_IEC_559__)有时被定义,而它不应该是”。这个陈述是否仍然准确?

1 个答案:

答案 0 :(得分:2)

  1. 我相信__GCC_IEC_559依赖于某些库功能,而且不能仅由编译器定义。有关一些信息,请参阅this post。这对于C来说并不罕见 - 编译器和C库有时必须合作才能实现整个标准。

  2. 您要问的内容取决于编译器。我认为你必须具备编译器的特殊知识才能做出决定。在GCC的特定情况下,它定义了一个宏来告诉你。在__GCC_IEC_559搜索onpageshow

  3. 嗯......我不知道这个问题的答案:-)。原始帖子似乎表明,是的,GCC可能会定义onpagehide,如果打算实施IEEE 754,即使它实际上没有这样做。

相关问题