【问题标题】:Will 'comparison between signed and unsigned integer expressions' ever actually result in errors?“有符号和无符号整数表达式之间的比较”实际上会导致错误吗?
【发布时间】:2013-01-27 22:22:54
【问题描述】:

我使用的对象通常会有(签名的)int 参数(例如int iSize),这些参数最终会存储某物应该有多大。同时,我会经常将它们初始化为-1,以表示对象(等)尚未设置/尚未填充/尚未准备好使用。

当我执行if( iSize >= someVector.size() ) { ... } 之类的操作时,我经常会收到警告comparison between signed and unsigned integer

因此,我名义上不想要使用unsigned int。是否有任何情况会导致错误或意外行为?

如果不是:处理此问题的最佳方法是什么?如果我使用编译器标志-Wno-sign-compare,我可能(假设)错过我应该使用unsigned int(或类似的东西)的情况。所以在与unsigned int 进行比较时,我是否应该只使用演员表——例如if( iSize >= (int)someVector.size() ) { ... }?

【问题讨论】:

  • Absolutely 它可能会导致意外(但已定义)的结果。

标签: c++ comparison int warnings unsigned


【解决方案1】:

是的,有,而且非常微妙。如果您好奇,可以查看 Stephan T. Lavavej 的 this interesting presentation 关于算术转换以及 Microsoft 的 STL 实现中由有符号与无符号比较引起的错误。

一般来说,问题是由于补码 2 算术,一个非常小的负整数值与一个非常大的无符号整数值具有相同的位表示(例如-1 = 0xFFFF = 65535)。

在检查size() 的特定情况下,为什么不首先使用size_t 类型作为iSize?无符号值只会给你更大的表现力,使用它。

如果您不想将iSize 声明为size_t,只需使用显式转换来明确说明您知道这种比较的性质。编译器试图帮助您处理这些警告,正如您正确写的那样,在某些情况下忽略它们可能会让您非常头疼。

因此,如果iSize 有时为负数(并且应该被评估为小于size() 的所有unsigned int 值),请使用成语:if ((iSize < 0) || ((unsigned)iSize < somevector.size())) ...

【讨论】:

  • 正如我所说,我将iSize 用于其他目的(带有负值)。因此,我似乎明确不想将其转换为无符号整数(不会 (unsigned int)-1 be > someVector.size() == true ?)。这就是为什么我明确询问我是否应该将.size() 转换为签名的int --- 你是说这是合适的解决方案吗?
  • @zhermes:是的,适当的解决方案是将size()的结果转换为signed intif (iSize < (int)v.size()) ...
  • @AndyProwl 这几乎总是合适的,因为您通常不想使用unsigned,除非在特殊情况下。根据平台(或以后确保可移植性),您可能需要编写和使用checked_cast,这将验证您转换的值是否在界限内。
  • @zhermes:您是否“绝对”确定将 size() 的结果(可能是 unsigned long)转换为 signed int 不会导致负数?有多确定?那是-1%确定吗? :)
  • @AndyProwl:这是否会让您重新评估“使用演员表:if(iSize >= (int)someVector.size())”的智慧?我想说正确的表达式,假设你的假设“如果 iSize 有时是负数(并且应该被评估为小于 size() 的所有无符号 int 值)”,将是if (iSize < 0 || (unsigned)iSize < somevector.size()),这是一个精确的陈述规定的目标。我坚持我的说法,即使用“未设置”指标重载 iSize 是次优的。
猜你喜欢
  • 2014-10-15
  • 1970-01-01
  • 1970-01-01
  • 2013-11-11
  • 2011-04-09
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多