我正试图在编译时确定支持_Float16
:
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <float.h>
#ifdef FLT16_MAX
_Float16 f16;
#endif
调用:
# gcc trunk on linux on x86_64
$ gcc -std=c11 -pedantic -Wall -Wextra
t0.c:4:1: warning: ISO C does not support the '_Float16' type [-Wpedantic]
# clang trunk on linux on x86_64
$ clang -std=c11 -pedantic -Wall -Wextra
t0.c:4:1: error: _Float16 is not supported on this target
在这里,我们看到了gcc和clang:
- 定义
FLT16_MAX
- 不支持
_Float16
主要问题:如何在编译时正确确定支持_Float16
?
额外的问题是:如果不支持相应的浮动类型,C11(或更新版本(标准是否要求不定义_MIN
/_MAX
宏?例如,对于整数类型(<stdint.h>
(,它是真的:;也不应定义相关的宏";(C11,7.20整数类型<stdint.h>,4(。浮动类型是否相同?
更新20211117:
- 调用不带
-pedantic
的gcc会导致警告消失。并且支持_Float16
。太棒了 - 在没有
-pedantic
的情况下调用clang不会导致错误消失。很显然,这是一只虫子
感谢用户n.1.8e9-where’s-my-share m的想法。
UPD20211118:gcc:使用-pedantic
定义了FLT16_MAX
,这是意外的(或者不是?(。
使用clang的__is_identifier
:https://clang.llvm.org/docs/LanguageExtensions.html#is-标识符
如果参数只是一个正则标识符而不是保留字,则
__is_identifier
的计算结果为1,因为它可以用作用户定义函数或变量的名称。否则计算结果为0。
所以希望这个代码能起作用:
#ifdef __is_identifier // Compatibility with non-clang compilers.
#if !__is_identifier(_Float16)
typedef _Float16 f16;
#define FLOAT16_BUILTIN
#endif
#endif
可以通过检查是否定义了相关的MIN / MAX
(和其他(宏来确定对_FloatN
的支持(在包含float.h
之前加上__STDC_WANT_IEC_60559_TYPES_EXT__
(。
额外:相同的原理用于确定对stdint.h
类型的支持:检查是否定义了关联的MIN / MAX
宏。
如何在编译时正确确定支持_Float16?
编译一个使用_Float16
的程序。如果它编译,则表示它受到支持。