【问题标题】:Is -1u valid c++?-1u 是有效的 C++ 吗?
【发布时间】:2012-01-13 13:44:01
【问题描述】:

例如

size_t x = -1u;

if (x == -1u)
    ...

有效吗?

如果这是有效的,它将阻止警告。 当然在 32 位系统上 x 应该是 0xffffffff 而在 64 位系统上 系统应该是0xffffffffffffffff。

-乔辰

【问题讨论】:

  • 文字总是非负数。这被解析为-(1u)
  • 如果你的目标是在 32 位系统上获得 0xFFFFFFFF 和在 64 位系统上获得 0xFFFFFFFFFFFFFFFF,那么写 size_t x = ~0U 不是更清楚吗?
  • ~0U 是所有位,-1U 是可能的最高数字。
  • @ruakh ...尽管这并不能解决size_tunsigned int 更宽的问题,这可能是OP 的想法。表达式 ~0U 的计算结果与 UINT_MAX 相同。
  • @Complicatedseebio:好点;我想它必须是~((size_t)0U)。或者只是 SIZE_MAX,假设 C99。

标签: c++ platform-independent


【解决方案1】:

虽然这是技术上有效的代码,但您依赖于实现相关的行为:将负数转换为无符号的溢出处理。但是,如果您需要有意义地将 size_t 与 -1 进行比较,因为您正在使用的 API 调用需要它,那么系统已经搞砸了,但您的代码可能会工作,因为他们不得不在另一边做同样的事情API。

【讨论】:

  • 我不是 C++ 专家,但我怀疑从有符号整数类型转换为无符号整数类型是在 C++ 中实现定义的,因为它是在 C99 中定义的。
  • 定义明确。我认为这类似于x % 2^32 32 位。
  • 没有负数转换为无符号数。 1uunsigned int 类型的正数,该正数使用一元 - 运算符求反。
  • size_t 几乎总是无符号的。
【解决方案2】:

我一直使用 ~0U 来表示“无符号,所有位都打开”。

【讨论】:

  • SIZE_MAX 在这种情况下可能更好,或者 ~0ULL 作为后备。
  • 但是注意不要写~0。这里的U 非常重要。如需进一步讨论,请参阅stackoverflow.com/questions/809227/…
  • 什么,因为我们担心反码硬件会回来?我认为那艘船已经航行了 :) 我的意思是,当然,U 更正确,但我希望你会看到比你尝试将典型应用程序移植到一个互补架构时更多的问题。
  • @StilesCrisis:补码不会回来,但在溢出时断言的系统仍然存在。
【解决方案3】:

编译器实现依赖的行为很烦人。不过,您应该能够做到这一点:

size_t x = 0;
x--;

if ((x+1) == 0)

【讨论】:

  • @Pubby:你认为这个答案中的什么表现出未定义的行为?
  • Pubby 你在哪里看到 UB?无符号类型(并且 size_t 是无符号类型)在溢出时具有明确定义的行为,它们环绕。 (有符号溢出是 UB)。
  • @AProgrammer 是这样吗?如果指向我的参考,我很乐意删除反对票。
  • @Pubby, "无符号整数,声明为无符号,应遵守算术模 2 定律n 其中 n 是特定大小的值表示中的位数整数。” 3.9.1/4 in C++-03
  • @AProgrammer 谢谢!为我的错误道歉。
【解决方案4】:

这可能是你想要的:

size_t x = -1ull;

if (x == -((size_t)-1ull))
    ...

x 将设置为可能的最大整数,可能不是所有位都设置。为此使用 ~0。

【讨论】:

  • 许多年后,当size_tunsigned long long 宽时,size_t x = -1ull;(也许size_t 作为一个宽uintmax_t 的typedef)将无法用x 初始化最大值。 size_t x = SIZE_MAX; 仍然有效。
【解决方案5】:

1u 的类型为 unsigned int。然后使用一元 - 运算符来否定它。行为如下:

无符号量的负数是通过从 2n 中减去其值来计算的,其中 n 是提升的操作数 (C++11 5.3.1/8) 中的位数。

-1u 因此保证为您提供unsigned int 可表示的最大值。

要获得任意无符号类型可表示的最大值,您可以将-1 强制转换为该类型。例如,对于std::size_t,考虑 static_cast<std::size_t>(-1).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多