-1和~0之间有区别吗?

比较无符号值时,如此测试中所示:

if (pos == (size_t)-1) 

这种比较在技术上是否与以下不同:

 if (pos == (size_t)~0) 

我不习惯第二种变体。 这就是我问这个问题的原因。 如果是的话,答案可能会相当直接。

C ++标准保证size_t是无符号类型,无符号类型遵循通常的模运算规则(其中模数是类型值表示中位数的2,参见3.9 / 4),因此-1转换为size_t必须是该类型可以表示的最大值。

0int ,并且~0表示int表示中的所有位都为零翻转。 该结果的值取决于平台上int的表示forms。 然后将该值(可能是陷阱表示,感谢@Matt McNabb)转换为size_t (这是按照模运算的规则完成的)。

总之,结果值是否相等是实现定义的。 (例如,如果int以二进制补码表示,则int的值为-1 ,因此两者相同。)

假设(由标准保证)size_t指的是无符号整数值 ,这个:

 if(pos == (size_t)~0) 

用于意图相当于:

 if(pos == (size_t)-1) 

假设机器使用2的补码表示负整数。 该标准没有强制执行,因此如果您希望您的代码100%可移植,则不应该假设它。

因此,在您的示例中, 技术上没有任何区别。 因为很难找到一个不会优化文字操作的编译器,如-1~0 。 以你的例子我完全得到:

  ; ... movq $-1, -16(%rbp) movq $-1, -8(%rbp) ; ... 

不要害怕那些-1 ,所谓无类型;)

更有趣的问题是,如果你的例子是:

 #include  int main() { int var0 = 0; int var1 = 1; size_t a = (size_t) -var1; size_t b = (size_t) ~var0; return a ^ b; } 

在我的情况下(Kubuntu,gcc 4.8.2,x86_64, -O0选项),感兴趣的部分是:

  movl $0, -24(%rbp) ; var0 = 0 movl $1, -20(%rbp) ; var1 = 1 movl -20(%rbp), %eax negl %eax ; 2's complement negation ; ... movl -24(%rbp), %eax notl %eax ; 1's complement negation ; ... 

查看英特尔手册:

NEG – 两个补充否定

用其二进制补码替换操作数(目标操作数)的值。 (此操作相当于从0减去操作数。)

NOT – 一个补语否定

在目标操作数上执行按位NOT运算(每个1设置为0,每个0设置为1),并将结果存储在目标操作数位置。

从理论上讲,我的结论是,在一些奇特的平台和编译器上,代码可能会有所不同,但是否则 – 否则。 如果不确定,请检查平台上的assembly清单。