【问题标题】:Why is there no underflow warning for unsigned type?为什么无符号类型没有下溢警告?
【发布时间】:2016-04-04 15:28:28
【问题描述】:

考虑以下代码:

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 &gt; -1) 上产生一个警告,用于比较有符号和无符号整数表达式。我对此没有异议。困扰我的是前两个赋值语句。

unsigned int n = 0;
unsigned int m = n - 1;

我的想法是编译器应该在第二次赋值时给我一个警告,因为它知道变量n 是无符号的,第一行的值为0,并且试图从一个零值并将其分配给无符号类型。

如果第二次赋值后的下一行恰好与 if 语句或类似语句不同,则相关代码可能已通过。

是的,在分配给 m 之前有一个缩小转换,是的,编译器没有抱怨它,Marshall Clow 在他的 C++Now 2017 Lightning Talk (Fighting Compiler Warnings) 中也提到了这一点。

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 语句中收到的警告是 有符号和无符号整数表达式之间的比较,这不是 unsigned int m = n - 1; 中发生的情况
  • 您是否尝试过使用 GCC 的 -Wall-Wextra 选项?
  • @Plouff:是的,我已经将 -Wall -Wextra 与 GCC 一起使用。

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


【解决方案1】:

原因是因为if (n &gt; -1) 永远不会是假的,但unsigned int m = n - 1; 是您可能想要编写的实际合法表达式。从 5/9 开始,有很多关于如何让您的已签名无符号类型具有一致类型的规则,除了最终的默认条件外,所有这些规则都失败了

否则,两个操作数都应转换为无符号整数 type 对应于带符号整数的操作数的类型 输入。

由于无符号算术被明确定义为使用模运算,因此整个表达式是合法且定义明确的。他们可能还决定发出警告,但可能有足够多的遗留代码使用这样的技巧,这会导致太多误报。

【讨论】:

  • 是否有免费的静态代码检查器会针对此类问题发出警告?
  • “遗留代码”:它确实不一定必须是遗留代码,这是用新代码编写的完全有效的东西。另一方面,将无符号类型用于 bigint 类型的代码(您想要回绕的地方)或位域通常是错误的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-10
  • 2011-02-15
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
相关资源
最近更新 更多