【问题标题】:casting signed to unsigned将签名转换为未签名
【发布时间】:2011-05-31 17:55:03
【问题描述】:

这样做是否正确?

typedef unsigned int Index;

enum
{
  InvalidIndex = (Index) -1 
};

我已经读过它跨平台是不安全的,但是我在很多“专业”代码中看到了这一点......

【问题讨论】:

  • 我希望你不要在每个问题的开头写“嗨”...

标签: c++ unsigned


【解决方案1】:

您阅读的内容可能是出于恐惧、不确定和怀疑。您阅读的任何内容的作者都可能认为(unsigned)-1 下溢并可能导致系统混乱,而位表示不会恰好为您提供UINT_MAX 来解决您的问题。

但是,作者错了,因为标准保证无符号值在到达其范围的边缘时会回绕。不管涉及什么位表示,(unsigned)-1 std::numeric_limits<unsigned>::max()。期间。

不过,我不确定它在这里有什么好处。你会得到那个大的,最大值。如果没问题,我想你很高兴。

【讨论】:

  • 您可能不知道enum 的底层类型,但您知道它将能够保存任何枚举常量的值,否则您将收到编译时错误。 UINT_MAX 是一个值,这是枚举常量可以采用的唯一合法值。
【解决方案2】:

如果您想获得 UINT_MAX,我很确定这实际上是最好的方法。将 -1 转换为 unsigned 保证产生 UINT_MAX。在 cmets 中有解释。

【讨论】:

  • UINT_MAX。并且它是有保证的,但 not 因为是按位符号表示。这是有保证的,因为转换为无符号类型会执行模运算。碰巧的是,使用 2 的补码表示,这会使位模式保持不变,但在 1 的补码和符号幅度中,它确实会改变位模式,并且强制转换保证可以完成这项工作。
  • 您的意思是INT_MAX,无论如何这里都是相关的UINT_MAX。不是因为位,而是因为标准说无符号值换行。然后,当您再次转换为 signed 以在枚举中使用时(if 基础类型已签名),您将返回 -1。
  • @Tomalak:“你得到 -1 回来” - 在实践中但不是原则上 (4.7/3)。
  • @Tomalak:我并不是说我喜欢这个规则,只是我喜欢在回答 SO 问题时指出它!
  • @SteveJessop:我并不是说我不同意这种行为;只是 C++ 不得不 来找点东西让我上手:P
【解决方案3】:

这是不安全的,因为没有明确定义枚举是什么。

有关更多信息,请参阅Are C++ enums signed or unsigned?

在一天结束时,您所写的内容看起来最终会在翻译中成为 (int)(unsigned int)(int) 所以我不确定您要完成什么。

【讨论】:

  • 绝对安全,因为表达式的值是完美定义的,要么该值可以在枚举中表示,要么就是一个错误。
【解决方案4】:

不太确定这是否是实现定义的,但是将 -1(显然是有符号的)转换为无符号整数会导致下溢,这通常会导致非常大的值(即 INT_MAX)。

【讨论】:

  • 这通常是编写这样的代码时的意图
  • 这并不是真正的下溢,因为无符号值被定义为环绕。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 2021-07-30
  • 2023-03-08
相关资源
最近更新 更多