Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ -1和~0之间有区别吗?_C++_C - Fatal编程技术网

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

C++ -1和~0之间有区别吗?,c++,c,C++,C,比较无符号值时,如本测试中所示: if (pos == (size_t)-1) 这种比较在技术上是否不同于: if (pos == (size_t)~0) 我不习惯第二种变体。这就是为什么我要问这个问题。如果答案是肯定的,答案可能是相当直接的。< P> C++标准保证 SiZeSt是无符号类型,无符号类型遵循通常的模块算术规则(其中模值是类型的值表示的二进制数的两倍,参见3.9/4),因此,转换为大小的-1必须是该类型可以表示的最大值 值0是一个int,并且~0具有翻转零的int表示中的所有

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

if (pos == (size_t)-1)
这种比较在技术上是否不同于:

if (pos == (size_t)~0)

我不习惯第二种变体。这就是为什么我要问这个问题。如果答案是肯定的,答案可能是相当直接的。

< P> C++标准保证<代码> SiZeSt是无符号类型,无符号类型遵循通常的模块算术规则(其中模值是类型的值表示的二进制数的两倍,参见3.9/4),因此,转换为
大小的
-1
必须是该类型可以表示的最大值

0
是一个
int
,并且
~0
具有翻转零的
int
表示中的所有位。该结果的值取决于平台上的
int
表示形式。然后将该值(感谢@Matt McNabb,它可能是陷阱表示)转换为
size\u t
(这是根据模运算规则完成的)

总之,结果值比较是否相等是由实现定义的。(例如,如果
int
用2的补码表示,则
~0
的值是
-1
,因此两者是相同的。)

,这是:

用于等同于:

if(pos == (size_t)-1)
假设机器使用负整数的表示形式。因此,如果您希望代码100%可移植,就不应该假设它是标准。

因此,在您的示例中,技术上没有任何区别。因为很难找到一个不会优化像
-1
~0
这样的文本操作的编译器。以你为例,我得到的确切信息如下:

        ; ...
        movq    $-1, -16(%rbp)
        movq    $-1, -8(%rbp)
        ; ...
不要害怕那些
-1
,assebmly是无类型的;)

更有趣的问题是,您的示例是否为:

#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;
}
查看英特尔手册:

NEG
-二的补码否定 将操作数(目标操作数)的值替换为其 二的补码。(此操作相当于 从0中减去操作数。)

-补码否定 执行按位NOT操作(每个1设置为0,每个0 在目标操作数和存储上设置为1) 目标操作数位置中的结果


从理论上讲,我的结论是,在某些异域平台和编译器上,代码可能会有所不同,但在其他情况下–不。如果不确定,请始终检查平台上的程序集列表。

好的
-1
转换为unsigned是因为我不认为我们可以说
~0
b/c取决于底层表示(直截了当)答案是否定的(没有区别)@barakmanos:那么直截了当的意思是错误的?不是一个精确的副本,但与
大小密切相关,t
总是无符号的。C11确实指定了-1如何转换为无符号的:6.3.1.3,第2段。值是
UINT\u MAX
@ShafikYaghmour
~0
是有符号的。
~0==0
很可能是在一个补码系统上,一个然后,转换到
大小\u t
的结果仍然是零。如果是
~0ULL
,那可能是另一回事。我见过有人称赞+0!=-0的机器。我不知道这是否是标准。@KerrekSB你说“取决于
int
在你的平台上的表示。”。出于兴趣,如果反转发生在cast之后,即
~(size\t)0)
。这会消除对
int
实现的依赖性吗?也就是说,
(size\t)-1
~(size\t)0)
将是等效的,会有更有力的保证吗?(我上一次评论中的打字修正)@尼尔:我相信是的,尽管我刚才没有把所有的部分都放在一起。
~
运算符被定义为一个补数,无符号整数的值是其值表示的二进制值(这是我缺少的部分),因此零的补数是“所有的一”这是最大的可表示的值。我认为它可能是标准所要求的。从C++草案;第3.9节,第7段;“积分类型的表示应该使用纯二进制记数系统来定义值。[示例:本国际标准允许整数类型使用2的补码、1的补码和带符号的幅值表示法。-结束示例]”+1我发现这是一对有趣的问答。@Niall:很难看出它还有什么其他意义,特别是如果你将3.9.1/4、3.9.1/7和脚注52结合起来。基本上,无符号整数有N个值位,位的值以通常的方式决定整数的值。实际上,只有有符号整数才有意义为实现细节留点余地。(当然,整数不需要唯一表示;它们很可能有填充。)注意,在补码中,
~0
可能是陷阱表示(负零)
#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;
}
        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

        ; ...