关于c中unsigned int的问题
可能的重复:
无符号 int 和有符号 char 比较
int j = 10;
unsigned int i = 10;
if( j > -1 )
printf("1\n");
else
printf("2\n");
if( i > -1 )
printf("3\n");
else
printf("4\n");
输出是:
1
4
我已经追踪到组装和比较是类似的:
cmp dword ptr [ebp-10h],0FFFFFFFFh
...
cmp dword ptr [ebp-14h],0FFFFFFFFh
但还是不明白为什么一个是真的,另一个是假的。
IMO cpu 不知道 dword ptr 是否已签名。
那么它在幕后是如何工作的呢?
更新
任何人都可以在汇编级别解释它吗?
Possible Duplicate:
unsigned int and signed char comparison
int j = 10;
unsigned int i = 10;
if( j > -1 )
printf("1\n");
else
printf("2\n");
if( i > -1 )
printf("3\n");
else
printf("4\n");
The output is :
1
4
I've traced into the assembly and the comparation is similar:
cmp dword ptr [ebp-10h],0FFFFFFFFh
...
cmp dword ptr [ebp-14h],0FFFFFFFFh
But still don't understand why one is true and the other is false.
IMO the cpu have no idea whether dword ptr
is signed or not.
So how does it work under the hood?
UPDATE
anyone can explain it in assembly level?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
正如 @Neil G 指出的,虽然
cmp
不知道无符号与有符号,但条件跳转指令知道。这样做是因为普通算术指令(如
sub
)会影响所有相关的条件代码,因此您可以直接进行条件跳转,而不需要进行任何显式比较。请注意,
cmp
只是一个sub
,不会影响目标。As @Neil G points out, while
cmp
doesn't know about unsigned vs signed, the conditional jump instructions do.This is done this way because normal arithmethic instructions (like
sub
) affect all the relevant condition codes, so then you can do a conditional jump directly, without needing to do any explicit comparison.Note that
cmp
is just asub
that doesn't affect the destination.在“>”之前运算符可以被求值,两边的操作数需要(概念上)转换为相同的类型。在这种情况下(不确定它是“标准”,还是只是编译器的突发奇想),-1 被转换为无符号。当然,-1 是 0xFFFFFFFF,在无符号比较中,它比 0x0000000A 更大,但在有符号比较中,它更小(因为高位是符号位,有符号负数几乎总是用“二进制补码”)。
“在幕后”我怀疑在您的CPU上生成的条件代码同时具有带符号和无符号部分,并且两个结果之间的差异与条件代码的检查方式有关,而不是与比较本身有关。
Before the ">" operator can be evaluated, the operands on both sides need to be (conceptually) converted to the same type. In this case (not sure if it's "standard", or just the whim of the compiler) the -1 is converted to unsigned. -1 is, of course, 0xFFFFFFFF, and that's larger, in an unsigned compare, than 0x0000000A, though in a signed compare it's smaller (because the high-order bit is the sign bit, and signed negative numbers are almost always represented in "twos-complement").
"Under the hood" I suspect that on your CPU the resulting condition code has both signed and unsigned sections, and the difference between the two results has to do with how the condition code is checked, rather than the compare itself.
当您比较无符号整型和有符号整型时,有符号整型将转换为无符号整型。将负有符号整数转换为无符号整数是通过添加 UINT_MAX + 1 来完成的。
因此 -1 会转换为 UINT_MAX + 1 - 1 = UINT_MAX,它优于 10。
另请参阅 “无符号保留”和“值保留”规则有什么区别?
When you compare an unsigned int and a signed int, the signed int is converted to unsigned int. Converting a negative signed int to a unsigned int is done by adding UINT_MAX + 1.
So -1 is converted to UINT_MAX + 1 - 1 = UINT_MAX which is superior to 10.
See also What's the difference between the "unsigned preserving" and "value preserving" rules?
正如其他答案所说,-1 正在转换为无符号整数。检查下面的跳转指令。一个应该是“ja”,另一个应该是“jg”:无符号和有符号跳转指令。
As the other answers say, -1 is being converted to unsigned int. Check the jump instructions that follow. One should be "ja" and the other "jg": the unsigned and signed jump instructions.
在下面的代码中:
-1 被转换为无符号整型,这是最大的无符号整型,并且明显大于 10。
在我的机器上,以下代码
产生:4294967295
In the following code:
the -1 is converted to an unsigned int, which is the biggest unsigned int and clearly larger than 10.
On my machine the following code
Yields: 4294967295
当比较无符号(即
i
)与有符号(即-1)时,编译器将有符号值转换为无符号值。将
-1
转换为无符号会给出一个非常大的值,因此( i > -1)
条件将产生 false。[6.3.1.3/2] (C99)
When comparing unsigned (i.e
i
) with signed (i.e -1) the compiler converts the signed value to unsigned.Converting
-1
to unsigned would give a very large value and so the( i > -1)
condition would yield false.[6.3.1.3/2] (C99)
这是您的程序,用它包含的所有隐式转换进行注释:
第一个比较是有符号整数的比较。第二个是无符号整数的比较。
关于您问题的另一方面,汇编中确实只有一条比较指令,但它设置了各种标志。您测试您感兴趣的标志以进行比较(有符号、无符号……)。
Here is your program annotated with all implicit casts it contains:
The first comparison is a comparison of signed ints. The second one is a comparison of unsigned ints.
Regarding the other aspect of your question, there is indeed only one comparison instruction in assembly, but it sets various flags. You test the flag you are interested in for the comparison you are doing (signed, unsigned,...).