我注意到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)规定:
宏UINTN_C(value)扩展为无符号整型常量uint_leastN_t类型
32位版本实际上扩展为无符号32位表示(uint_least32_t
在这个CPU上是unsigned long
)。
然而,16位版本扩展为有符号表示:UINT16_C(1)
扩展为1
,类型为int
。
这和标准不矛盾吗?
为什么不像#define __UINT16_C(c) ((uint_least16_t)(c))
这样做呢?
C不识别类型小于int
和unsigned int
的数字字面值的概念。在int
为32位的平台上,由于整数提升,表达式(uint16_t)123
将表现为类型signed int
,并且包含假定类型uint16_t
的数字字面值的表达式的行为方式与该类型的任何其他表达式的处理方式不一致,这有点不合逻辑。