为什么没有无符号类型的下溢警告?

时间:2016-04-04 15:28:29

标签: c++ gcc visual-c++ clang++

请考虑以下代码:

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(战斗编译器警告)中也提到了

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)
  • Microsoft C / C ++ 19.00.23506

1 个答案:

答案 0 :(得分:1)

The reason is because if (n > -1) can never be false, but unsigned int m = n - 1; is an actual legal expression you may have wanted to write. From 5/9 there are a bunch of rules about how to get your signed an unsigned types to have a consistent type, and all of them fail except the final default condition

Otherwise, both operands shall be converted to the unsigned integer type corresponding to the type of the operand with signed integer type.

Since unsigned arithmetic is well-defined to use modulo operations the entire expression is legal and well defined. They could yet decide to emit a warning but there may be enough legacy code using tricks like this that it would cause too many false positives.