c-如何在编译时正确确定支持_Float16



我正试图在编译时确定支持_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:

  1. 调用不带-pedantic的gcc会导致警告消失。并且支持_Float16。太棒了
  2. 在没有-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的程序。如果它编译,则表示它受到支持。

最新更新