问题 -1u是有效的c ++吗?


例如

size_t x = -1u;

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

有效?

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

-Jochen


4075
2017-12-05 20:54


起源

文字总是非负面的。这被解析为 -(1u)。 - Kerrek SB
如果你的目标是获得 0xFFFFFFFF 在32位系统和 0xFFFFFFFFFFFFFFFF 在64位系统上,编写它会不会更清晰 size_t x = ~0U? - ruakh
〜0U全部为开,-1U为最高数。 - Pubby
@ruakh ......虽然这并没有解决问题所在 size_t 比...宽 unsigned int,这可能是OP的想法。表达方式 ~0U 评估为相同的值 UINT_MAX。 - Pascal Cuoq
@Complicatedseebio:好点;我想它必须是 ~((size_t)0U)。要不就 SIZE_MAX,假设C99。 - ruakh


答案:


1u 有类型 unsigned int。然后使用一元来否定这一点 - 运营商。行为如下:

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

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

要获得可由任意无符号类型表示的最大值,可以进行强制转换 -1 到那种类型。例如,对于 std::size_t考虑一下   static_cast<std::size_t>(-1)


7
2017-12-05 21:21





我总是使用~0U来达到“无符号,所有位都开启”的目的。


5
2017-12-05 21:00



...这对64位不起作用 size_t。 - Brett Hale
在这种情况下,SIZE_MAX可能更好,或者~0ULL作为后备。 - StilesCrisis
但要注意不要写 ~0。该 U 在这里非常重要。有关进一步讨论,请参阅 stackoverflow.com/questions/809227/... - Johannes Schaub - litb
什么,因为我们担心会有补充硬件回来?我认为这艘船已经航行了:)我的意思是,肯定的是,U更正确,但我希望你看到的问题比你试图将一个典型的应用程序移植到一个补充架构上的问题要多得多。 - StilesCrisis
@StileCrisis:一个人的补充不会回来,但在溢出时断言的系统仍在我们身边。 - Joshua


编译器实现依赖行为很烦人。但是你应该能够做到这一点:

size_t x = 0;
x--;

if ((x+1) == 0)

1
2017-12-05 21:16



这是未定义的行为。他发布的代码不是。 - Pubby
@Pubby:你觉得这个答案中有什么展示未定义的行为? - James McNellis
Pubby你在哪里看到UB?无符号类型(和size_t是无符号类型)在溢出时具有良好定义的行为,它们包围。 (签名溢出是UB)。 - AProgrammer
@Pubby,“无符号整数,声明无符号整数,应遵守算术模2 <sup> n </ sup>的定律,其中n是整数特定大小的值表示中的位数。” 3.9.1 / 4 in C ++ - 03 - AProgrammer
@AProgrammer谢谢!为我的错误道歉。 - Pubby


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


0
2017-12-05 21:00



我不是C ++专家,但我怀疑从有符号整数类型转换为无符号整数类型是在C ++中实现定义的,因为它是在C99中定义的。 - Pascal Cuoq
它定义明确。我觉得它就像是 x % 2^32 为32位。 - Pubby
没有负数转换为无符号。 1u 是一个正数的类型 unsigned int,使用一元来否定正数 - 运营商。 - James McNellis
size_t几乎总是无符号的。 - Joshua


这可能是你想要的:

size_t x = -1ull;

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

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


0
2017-12-05 21:21



从现在开始很多年 size_t 比...宽 unsigned long long, size_t x = -1ull; (也许 size_t 作为一个广泛的typedef uintmax_t)将无法草签 x 具有最大值。 size_t x = SIZE_MAX; 仍然有效。 - chux