在C语言中,-1是表达式,以及关于他的默认类型

首先,看一个宏:

#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比较应该相等。

学习到几个点:

  1. 整型常量的类型按照下图来确定。备注a中提到,按能够满足的最小范围的确定整型类型。因此,1是整型常量,-1不是。
    image

  2. 在 《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;
    }
}