GCC:为什么无法在 -std=c11 -Wall 下编译干净的 printf("%f\n", f16) ?

Pav*_*kin 4 c printf gcc language-lawyer half-precision-float

示例代码:

#include <stdio.h>
#define __STDC_WANT_IEC_60559_TYPES_EXT__
#include <float.h>

#ifdef FLT16_MAX
_Float16 f16;
int main(void)
{
    printf("%f\n", f16);
    return 0;
}
#endif
Run Code Online (Sandbox Code Playgroud)

调用:

# gcc trunk on linux on x86_64
$ gcc t0.c -std=c11 -Wall
Run Code Online (Sandbox Code Playgroud)

预期诊断:

<nothing>
Run Code Online (Sandbox Code Playgroud)

实际诊断:

t0.c:9:14: warning: format '%f' expects argument of type 'double', but argument 2 has type '_Float16' [-Wformat=]
    9 |     printf("%f\n", f16);
      |             ~^     ~~~
      |              |     |
      |              |     _Float16
      |              double
Run Code Online (Sandbox Code Playgroud)

这是否意味着在__STDC_WANT_IEC_60559_TYPES_EXT__AND 下如果FLT16_MAX定义了 gcc 不知道printf可以与 一起使用_Float16?是否应该有所了解?

另外:尽管printf("%f\n", f);.whenf是 a ,float但上面不会出现任何警告format '%f' expects argument of type 'double', but argument 2 has type 'float'。使困惑。

Bar*_*mar 9

来自clang 手册

由于默认参数提升仅适用于标准浮点类型,因此当作为可变参数或无类型参数传递时_Float16,值不会提升double。因此,在使用某些图书馆设施时必须小心_Float16;例如, 没有printf格式说明符_Float16,并且(与 不同)它在传递给 时float不会隐式提升为,因此程序员必须在将其与或类似说明符一起使用之前显式将其转换为 double 。doubleprintf%f

  • 是的,就是这个意思。 (2认同)