有符号/无符号不匹配一定很糟糕吗?
这是我的程序:
int main(int argc, char *argv[]) {
unsigned int i;
for (i = 1; i < argc; i++) { // signed/unsigned mismatch here
}
}
argc
签了,i
不是。这是一个问题吗?
“有符号/无符号不匹配”可能很糟糕。在您的问题中,您是在询问比较。当比较相同基类型但一个有符号和一个无符号的两个值时,有符号值将转换为无符号值。所以,
int i = -1;
unsigned int j = 10;
if (i < j)
printf("1\n");
else
printf("2\n");
打印 2,而不是 1。这是因为 in i < j
,i
被转换为unsigned int
。 (unsigned int)-1
等于UINT_MAX
,一个很大的数。因此,条件评估为假,然后您就进入了else
子句。
对于您的特定示例,argc
保证为非负数,因此您不必担心“不匹配”。
在您的特定情况下,这不是一个真正的问题,但编译器无法知道 argc 将始终具有不会导致任何问题的值。
这只是间接的问题。
如果您将有符号整数用于按位运算,例如 、 和 ,则可能会发生&
不好的|
事情。如果您使用无符号整数进行算术运算(下溢、测试数字是否为无限循环等)
,则可能会发生完全不同的坏事。<<
>>
>= 0
因此,当您在任一类型的操作(算术或位操作)中混合有符号和无符号整数时,一些编译器和静态检查工具会发出警告。
尽管在像您的示例这样的简单情况下混合它们是安全的,但如果这样做,则意味着您不能使用那些静态检查工具(或必须禁用这些警告),这可能意味着其他错误未被检测到。
有时您别无选择,例如size_t
在内存管理代码中对类型值进行算术运算时。
在您的示例中,我会坚持使用int
,只是因为具有更少的类型更简单,并且int
无论如何都会在那里,因为它是 . 的第一个参数的类型main()
。
不算太差。我会修复有关有符号/无符号不匹配的编译器警告,因为即使不太可能或不可能发生坏事也可能发生。当您因为有符号/无符号不匹配而必须修复错误时,编译器基本上是在说“我告诉过你”。不要忽略它那里的警告是有原因的。