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

GCC: why cannot compile clean printf("%f\n", f16) under -std=c11 -Wall?

示例代码:

#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

调用:

# gcc trunk on linux on x86_64
$ gcc t0.c -std=c11 -Wall

预期诊断:

<nothing>

实际诊断:

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

这是否意味着在 __STDC_WANT_IEC_60559_TYPES_EXT__ 下并且如果 FLT16_MAX 定义 gcc 不知道 printf 可以与 _Float16 一起使用?它应该知道吗?

另外:printf("%f\n", f);ffloat 时,尽管 format '%f' expects argument of type 'double', but argument 2 has type 'float' 没有上面的警告。困惑。

来自clang manual

Because default argument promotion only applies to the standard floating-point types, _Float16 values are not promoted to double when passed as variadic or untyped arguments. As a consequence, some caution must be taken when using certain library facilities with _Float16; for example, there is no printf format specifier for _Float16, and (unlike float) it will not be implicitly promoted to double when passed to printf, so the programmer must explicitly cast it to double before using it with an %f or similar specifier.