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