首先,看一个宏:
#define COMPARE_MINUS_ONE(x) if(x == -1){\
printf("IS -1\n"); } else {\
printf("IS %d\n", x); }
乍一看好像和-1比较,相同打印-1,不同打印对应的值。但是如果这样写
uint16_t x = -1;
COMPARE_MINUS_ONE(x) // 以为结果是-1,但是结果打印出来是65535
我以为x的值是0xFFFF,想当然地以为,和-1比较应该相等。
学习到几个点:
整型常量的类型按照下图来确定。备注a中提到,按能够满足的最小范围的确定整型类型。因此,1是整型常量,-1不是。
在 《C a Reference Manual》有第五版的2.7小节,有这样一句话:
The value of an integer constant is always non-negative in the absence of overflow. If there is a preceding minus sign, it is taken to be a unary operator applied to the constant,
not part of the constant.
意思是:整形常量总是非负数。如果整型常量前面有-符号,说明这是表达式。所以-1
是表达式。
综上:-1
是表达式,结果类型是int。因此,将 uint16_t 的x与 -1 比较时,x会发生整型提升,提升结果是int类型的65535。
因此可以明确转换-1的类型为uint16_t
#define COMPARE_MINUS_ONE(x) \
if(x == (uint16_t)-1){ \
printf("IS -1\n"); } else {\
printf("IS %d\n", x); }
如果用C++,可以用模板类代替宏
// 使用模板函数替代宏
template<typename T>
void print_log(T x) {
std::cout << std::numeric_limits<T>::max() << std::endl;
if (x == std::numeric_limits<T>::max()) {
std::cout << "," << std::endl;
} else {
std::cout << ", " << x << std::endl;
}
}