arm-none-eabi-gcc 中 UINT16_C 的定义错误?

Wrong definition of UINT16_C in arm-none-eabi-gcc?

我注意到 arm-none-eabi-gcc 10.2 以下列方式定义宏 UINTN_C(使用 -mcpu=cortex-m7 -std=c99 -g3 -O0 编译):

#define UINT32_C(x) __UINT32_C(x)  
#define UINT16_C(x) __UINT16_C(x) 

然后

#define __UINT32_C(c) c ## UL
#define __UINT16_C(c) c

C99 标准 (7.18.4.1 p2) 说:

The macro UINTN_C(value) shall expand to an unsigned integer constant with the specified value and type uint_leastN_t.

32 位版本确实扩展到无符号的 32 位表示(uint_least32_t 在这个 CPU 上是 unsigned long)。

但是 16 位版本扩展为有符号表示:UINT16_C(1) 扩展为 1 类型 int.

这不是与标准相矛盾吗?是否有 gcc 选项可以解决这个问题?

为什么不做类似 #define __UINT16_C(c) ((uint_least16_t)(c)) 的事情?

C 无法识别类型小于 intunsigned int 的数字文字的概念。在 int 是 32 位的平台上,表达式 (uint16_t)123 将作为整数提升的结果表现为类型 signed int,并且对于包含数字文字的表达式来说有点不合逻辑假定类型 uint16_t 的行为方式与处理该类型的任何其他表达式的方式不一致。