宏在“stdint.h ”UINT8_C
中定义,具有以下规范:宏UINTN_C(value)
应扩展为对应于类型的整数常量表达式uint_leastN_t
。
然而,在野外,实现有所不同:
#define UINT8_C(value) ((uint8_t) __CONCAT(value, U)) // AVR-libc
#define UINT8_C(x_) (static_cast<std::uint8_t>(x_)) // QP/C++
#define UINT8_C(c) c // GNU C Library
前两个实现看起来大致相同,但第三个的行为不同:例如,以下程序1
使用 AVR-libc 和 QP/C++ 打印,但-1
使用 glibc(因为有符号值的右移会传播符号位)。
std::cout << (UINT8_C(-1) >> 7) << std::endl; // prints -1 in glibc
的实现UINT16_C
显示相同的行为,但不是UINT32_C
,因为它的定义包含U
后缀:
#define UINT32_C(c) c ## U
有趣的是,由于错误报告,glibc 的定义在 2006 年UINT8_C
发生了变化。之前的定义是,但是由于整数提升规则,它产生了不正确的输出 ( ) 。#define UINT8_C(c) c ## U
false
-1 < UINT8_C(0)
根据标准,这三个定义都正确吗?这三个实现之间是否还有其他区别(除了负常数的处理)?