比较无符号值时,如此测试:
if (pos == (size_t)-1)
这种比较技术上是否与以下内容不同:
if (pos == (size_t)~0)
我不习惯第二种变体。这就是我问这个问题的原因。如果是的话,答案可能会相当直接。
答案 0 :(得分:27)
C ++标准保证size_t
是无符号类型,无符号类型遵循通常的模运算规则(其中模数是类型值表示中位数的2,参见3.9 / 4),因此转换为-1
的{{1}}必须是该类型可以表示的最大值。
值size_t
是0
,int
将~0
表示中的所有位都翻转为零。该结果的值取决于您平台上int
的表示形式。然后将该值(可能是陷阱表示,感谢@Matt McNabb)转换为int
(遵循模运算规则)。
总之,结果值是否相等是实现定义的。 (例如,如果size_t
以两个补码表示,则int
的值为~0
,因此两者相同。)
答案 1 :(得分:19)
Assuming (guaranteed by the standard) that size_t refers to an unsigned integer value,这个:
if(pos == (size_t)~0)
意图相当于:
if(pos == (size_t)-1)
假设机器使用2's complement表示负整数。标准doesn't enforce it因此,如果您希望代码100%可移植,则不应该采用此标准。
答案 2 :(得分:1)
因此,在您的示例技术上,没有任何区别。因为很难找到不会优化-1
和~0
等文字操作的编译器。以你的榜样,我完全得到了:
; ...
movq $-1, -16(%rbp)
movq $-1, -8(%rbp)
; ...
不要害怕那些
-1
,而且它们是无类型的;)
更有趣的问题是,如果你的例子是:
#include <stddef.h>
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)并存储 结果在目标操作数位置。
我的结论是,理论上,代码可能在某些奇特的平台和编译器上有所不同,但在其他方面 - 否则。如果不确定,请检查平台上的装配清单。