为什么unsigned类型没有下溢警告?
Why is there no underflow warning for unsigned type?
考虑以下代码:
unsigned int n = 0;
unsigned int m = n - 1; // no warning here?
if (n > -1) {
std::cout << "n > -1.\n";
} else {
std::cout << "yes, 0 is not > -1.\n";
}
上面的代码在 if
条件 if (m > -1)
上产生警告,用于比较有符号和无符号整数表达式。我对此没有异议。困扰我的是前两个赋值语句。
unsigned int n = 0;
unsigned int m = n - 1;
我的想法是,编译器应该在第二次赋值时给我一个警告,因为它知道变量 n
是无符号的,第一行的值为 0
并且那里试图从零值中减去并将其分配给无符号类型。
如果第二次赋值后的下一行碰巧不同于 if
语句或类似的东西,那么相关代码可能已经漏掉了。
是的,在分配给 m
之前有一个收缩转换,是的,编译器不会抱怨它,Marshall Clow 在他的 C++Now 2017 Lightning Talk 中也提到了这一点(Fighting Compiler警告)。
short s = 3 * 6;
short s = integer * integer;
short s = integer;
那么,为什么编译器不能告诉我该代码中可能存在的下溢?
编译器:
- Clang 3.7/4.0 (-Wall -Wextra)
- GCC 5.3/7.1.1(-Wall -Wextra -pedantic)
- 微软 C/C++ 19.00.23506
原因是因为 if (n > -1)
永远不会为假,但 unsigned int m = n - 1;
是您可能想要编写的实际合法表达式。从 5 月 9 日开始,有一堆关于如何让你的有符号和无符号类型具有一致类型的规则,除了最终的默认条件
之外,所有这些都失败了
Otherwise, both operands shall be converted to the unsigned integer
type corresponding to the type of the operand with signed integer
type.
由于无符号算术被明确定义为使用模运算,因此整个表达式是合法且定义明确的。他们仍然可以决定发出警告,但可能有足够多的遗留代码使用这样的技巧,这会导致太多误报。
考虑以下代码:
unsigned int n = 0;
unsigned int m = n - 1; // no warning here?
if (n > -1) {
std::cout << "n > -1.\n";
} else {
std::cout << "yes, 0 is not > -1.\n";
}
上面的代码在 if
条件 if (m > -1)
上产生警告,用于比较有符号和无符号整数表达式。我对此没有异议。困扰我的是前两个赋值语句。
unsigned int n = 0;
unsigned int m = n - 1;
我的想法是,编译器应该在第二次赋值时给我一个警告,因为它知道变量 n
是无符号的,第一行的值为 0
并且那里试图从零值中减去并将其分配给无符号类型。
如果第二次赋值后的下一行碰巧不同于 if
语句或类似的东西,那么相关代码可能已经漏掉了。
是的,在分配给 m
之前有一个收缩转换,是的,编译器不会抱怨它,Marshall Clow 在他的 C++Now 2017 Lightning Talk 中也提到了这一点(Fighting Compiler警告)。
short s = 3 * 6;
short s = integer * integer;
short s = integer;
那么,为什么编译器不能告诉我该代码中可能存在的下溢?
编译器:
- Clang 3.7/4.0 (-Wall -Wextra)
- GCC 5.3/7.1.1(-Wall -Wextra -pedantic)
- 微软 C/C++ 19.00.23506
原因是因为 if (n > -1)
永远不会为假,但 unsigned int m = n - 1;
是您可能想要编写的实际合法表达式。从 5 月 9 日开始,有一堆关于如何让你的有符号和无符号类型具有一致类型的规则,除了最终的默认条件
Otherwise, both operands shall be converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
由于无符号算术被明确定义为使用模运算,因此整个表达式是合法且定义明确的。他们仍然可以决定发出警告,但可能有足够多的遗留代码使用这样的技巧,这会导致太多误报。