【问题标题】:Is comparing signed and unsigned integer safe? [duplicate]比较有符号和无符号整数是否安全? [复制]
【发布时间】:2017-07-27 13:39:57
【问题描述】:

在此代码示例中使用 int 而不是 std::size_t

std::vector<int> v {1,2,3,4};
for(int i = 0; i < v.size(); i++)
{
  std::cout << v[i] << " ";
}

编译器生成以下警告:

warning: comparison between signed and unsigned integer expressions

但是程序按预期运行并输出:

1 2 3 4

我还经常在我正在从事的项目中注意到这些警告,这些警告已经运行多年,并且这些警告从未给我们的客户带来任何问题。由于显然这些程序在比较有符号和无符号整数方面没有问题,我想问一下:

  • 在适用的情况下始终使用无符号整数是否有任何好处、性能或安全方面?
  • 在什么情况下(如果有)比较有符号和无符号整数会导致错误或意外行为?
  • 如果没有充分的理由担心这些警告,是否有任何历史原因,为什么这些信息可能对过去的开发人员有用?

【问题讨论】:

  • 你可以(并且应该)通过写for(size_t i = 0; i &lt; v.size(); i++)来轻松修复该警告
  • 有符号和无符号类型具有可在两种类型中表示的共同值范围。只要所有值都保持在该范围内,它就可以工作。一旦单个值超出该范围,它就会中断。

标签: c++ compiler-warnings


【解决方案1】:

比较无符号和有符号可能有严重的问题,例如

std::string( "Bah" ).size() < -5

……永远是真的。

这就是您收到警告的原因,但编译器不够聪明,在分配的时间范围内,无法看到任何特定的此类比较都是安全的。

现在是你的要点问题。

在适用的情况下始终使用无符号整数对性能或安全有什么好处?

是的,为了正确起见,避免使用 UB。 但是,“适用”是你做比特级事情的地方。对于数字,总是首选有符号整数或浮点类型。

在什么情况下(如果有)比较有符号和无符号整数会导致错误或意外行为?

当涉及无符号环绕时,通常是通过将操作数从有符号隐式提升为无符号。

如果没有充分的理由担心这些警告,是否有任何历史原因,为什么这些信息可能对过去的开发人员有用?

不适用。

【讨论】:

    【解决方案2】:

    在开始比较负数之前是安全的。

    无符号整数可以容纳两倍于普通整数,但不能容纳 负值。

    【讨论】:

    • 比较对于有符号整数来说太大但不是无符号的数字呢?
    • v.size() 也可能返回unsigned long long 并超出int 范围。
    • @George True aswell
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-28
    • 2015-08-28
    • 2011-07-21
    • 2014-10-15
    相关资源
    最近更新 更多