5

有符号/无符号不匹配一定很糟糕吗?

这是我的程序:

int main(int argc, char *argv[]) {
    unsigned int i;

    for (i = 1; i < argc; i++) { // signed/unsigned mismatch here

    }
}

argc签了,i不是。这是一个问题吗?

4

4 回答 4

9

“有符号/无符号不匹配”可能很糟糕。在您的问题中,您是在询问比较。当比较相同基类型但一个有符号和一个无符号的两个值时,有符号值将转换为无符号值。所以,

int i = -1;
unsigned int j = 10;

if (i < j)
    printf("1\n");
else
    printf("2\n");

打印 2,而不是 1。这是因为 in i < ji被转换为unsigned int(unsigned int)-1等于UINT_MAX,一个很大的数。因此,条件评估为假,然后您就进入了else子句。

对于您的特定示例,argc保证为非负数,因此您不必担心“不匹配”。

于 2010-02-14T21:01:53.067 回答
1

在您的特定情况下,这不是一个真正的问题,但编译器无法知道 argc 将始终具有不会导致任何问题的值。

于 2010-02-14T21:02:06.133 回答
1

这只是间接的问题。

如果您将有符号整数用于按位运算,例如 、 和 ,则可能会发生&不好的|事情。如果您使用无符号整数进行算术运算(下溢、测试数字是否为无限循环等) ,则可能会发生完全不同的坏事。<<>>
>= 0

因此,当您在任一类型的操作(算术或位操作)中混合有符号和无符号整数时,一些编译器和静态检查工具会发出警告。

尽管在像您的示例这样的简单情况下混合它们是安全的,但如果这样做,则意味着您不能使用那些静态检查工具(或必须禁用这些警告),这可能意味着其他错误未被检测到。

有时您别无选择,例如size_t在内存管理代码中对类型值进行算术运算时。

在您的示例中,我会坚持使用int,只是因为具有更少的类型更简单,并且int无论如何都会在那里,因为它是 . 的第一个参数的类型main()

于 2010-02-14T21:10:09.970 回答
1

不算太差。我会修复有关有符号/无符号不匹配的编译器警告,因为即使不太可能或不可能发生坏事也可能发生。当您因为有符号/无符号不匹配而必须修复错误时,编译器基本上是在说“我告诉过你”。不要忽略它那里的警告是有原因的。

于 2010-02-14T21:45:12.340 回答