2010-02-14 55 views
5

有符号/无符号不匹配必然不好吗?C89:有符号/无符号不匹配

这里是我的程序:

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

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

    } 
} 

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

+0

不是一个愚蠢的,但值得阅读:http://stackoverflow.com/questions/859943/c-how-can-i-fix-warnings-like-comparison-between-signed-and- unsigned – finnw

回答

9

“有符号/无符号不匹配”可能不好。在你的问题中,你在问比较。比较相同基本类型的两个值时,一个有符号值和一个无符号值时,有符号值将转换为无符号值。所以,

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

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

印刷品2,而不是1。这是因为在i < ji转换为unsigned int(unsigned int)-1等于UINT_MAX,这是一个非常大的数字。条件因此评估为false,并且您会看到else子句。

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

+0

为什么签名转换为无符号(为什么不反过来)?这种行为标准化? – triclosan

+0

@ ticlosan,是的。规则稍微复杂一点,但对于int和unsigned int,由于它们具有相同的等级,因此将有符号类型转换为无符号类型。参见第6节。详情请参阅N1256的3.1.8。 –

1

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

+0

如果'argc'太大而无法放入'int',则无论如何您都会遇到严重的问题:-) – finnw

+0

不一定。 'INT_MAX'可以低至32767,我看到命令行超过几百千字节。已知xargs(1)实用程序很容易达到此限制。 – Jens

1

这只是间接的一个问题。如果你使用的位运算,如&|<<>>符号整数

坏事情都可能发生。如果您使用无符号整数算术(下溢,无限循环测试时,如果一个号码是>= 0等)

因此
完全不同的坏事情都可能发生,一些编译器和静态检查工具将当你混合发出警告(算术或位操作)

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

有时你没有选择,例如当在内存管理代码中对size_t类型的值进行算术运算时。

在你的例子,我会坚持int,只是因为它是简单的有种类少,且int将是在那里呢,因为它是第一个参数main()的类型。

1

它还不错。我会修正有关签名/未签名不匹配的编译器警告,因为即使它们不可能或不可能发生,也可能发生坏事。当你必须修正由于签名/未签名不匹配导致的错误时,编译器基本上会说“我已经告诉过你了”。不要忽视它出于某种原因的警告。