我有一个简单的 C 程序。
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
bool foo (unsigned int a) {
return (a > -2L);
}
bool bar (unsigned long a) {
return (a > -2L);
}
int main() {
printf("foo returned = %d\n", foo(99));
printf("bar returned = %d\n", bar(99));
return 0;
}
当我运行这个程序时的输出如下:
foo returned = 1
bar returned = 0
这里有在godbolt上重新创建的链接here
我的问题是为什么foo(99)
返回true但bar(99)
返回false。
对我来说,bar
返回false是有道理的。为了简单起见,假设长整型为8位,然后(使用补码表示有符号值):
99 == 0110 0011
-2 == unsigned 254 == 1111 1110
显然,CMP指令将看到1111 1110更大,并返回false。
但是我不明白foo
函数背后正在发生什么。 foo
的汇编似乎硬编码为始终返回mov eax,0x1
。 我本来希望foo
做类似于bar
的事情,这里到底发生了什么?
-2
的long
类型进行比较,对于foo
函数而言,这意味着无符号整数变量a
将被转换为普通的long
类型。算术运算(包括比较操作)使用更大的数据类型进行计算。 - Some programmer dudelong
可以表示所有unsigned int
的值时,unsigned int
才会被转换为long
。 如果long
与unsigned int
具有相同的宽度,则通常算术转换的最后一条规则适用,即两个操作数都将转换为与有符号整数操作数类型相对应的无符号类型,这将是unsigned long
。请注意,不改变原文意思的前提下,本翻译可能不如原文精准。 - Eric Postpischil