现代 C 编译器的 __STDC_IEC_559__ 状态 [英] Status of __STDC_IEC_559__ with modern C compilers

查看:26
本文介绍了现代 C 编译器的 __STDC_IEC_559__ 状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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__.

根据 GCC 的文档,它没有定义 __STDC_IEC_559__.

我使用 GCC 4.9.2 和 Clang 3.6.0 测试了这个,两者都使用 glibc 2.21 使用以下代码.

//test.c//#include <features.h>诠释主要(无效){#如果定义(__STDC_IEC_559__)//#如果定义(__GCC_IEC_559__)返回 1;#别的返回0;#万一}

然后

回显 $?

这表明使用此代码 __STDC_IEC_559__ 是用 GCC 定义的,而不是用 Clang 定义的.然后我做了 gcc -E 并显示文件 stdc-predef.h 被包含在内.此文件定义 __STDC_IEC_559__.

/* glibc 的目的是支持 IEC 559 数学功能,真正的和复杂.如果 GCC(4.9 和更高版本)预定义宏指定编译器意图可用,使用它们来确定总体意图是否是支持这些功能;否则,假设一个较旧的编译器打算支持这些特性,并且默认情况下定义这些宏.*/#ifdef __GCC_IEC_559# 如果 __GCC_IEC_559 >0# 定义 __STDC_IEC_559__ 1# 万一#别的# 定义 __STDC_IEC_559__ 1#万一

这确认是 glibc 定义了这个宏,而不是 GCC.

但是,当我包含 features.h(或 stdio.h)时,Clang 也包含此文件,并且 __STDC_IEC_559__ 是已定义.

所以 __STDC_IEC_559__ 是由 GCC 和 Clang 定义的(带有 glibc 头文件),这似乎不同意我链接到的第一个问题的答案.p>

然后我测试了 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. 我相信 __STDC_IEC_559__ 依赖于一些库特性,不能单独由编译器定义.有关一些信息,请参阅这篇文章.这对 C 来说并不少见——编译器和 C 库有时必须合作才能实现整个标准.

  2. 您的要求取决于编译器.我认为您必须对编译器有特殊的了解才能做出决定.在 GCC 的具体情况下,它定义了一个宏来告诉你.在手册的这个节点中搜索__GCC_IEC_559.

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

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):

  1. Why is __STDC_IEC_559__ defined by glibc and not by the compiler?
  2. 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.g 1.0/-0.0). Is there documentations for this or a macro to test for this?
  3. 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?

解决方案

  1. 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.

  2. 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.

  3. 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.

这篇关于现代 C 编译器的 __STDC_IEC_559__ 状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆