【问题标题】:C89: signed/unsigned mismatchC89:有符号/无符号不匹配
【发布时间】:2010-02-14 20:56:25
【问题描述】:

有符号/无符号不匹配是否一定不好?

这是我的程序:

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

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

    }
}

argc 已签名,i 未签名。这是个问题吗?

【问题讨论】:

标签: size c89


【解决方案1】:

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

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

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

打印 2,而不是 1。这是因为在 i &lt; j 中,i 被转换为 unsigned int(unsigned int)-1 等于 UINT_MAX,一个非常大的数字。因此,该条件的计算结果为 false,您将得到 else 子句。

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

【讨论】:

  • 为什么有符号转换为无符号(为什么不反过来)?这种行为标准化了吗?
  • @triclosan,是的。规则稍微复杂一些,但是对于intunsigned int,由于它们具有相同的等级,所以将有符号类型转换为无符号类型。有关详细信息,请参阅 N1256 的第 6.3.1.8 节。
【解决方案2】:

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

【讨论】:

  • 如果argc 太大而无法放入int,无论如何你都会遇到严重的问题:-)
  • 不一定。 INT_MAX 可以低至 32767,我见过超过几百 KB 的命令行。众所周知,xargs(1) 实用程序很容易达到该限制。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    这只是间接的问题。

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 2014-06-13
      • 1970-01-01
      相关资源
      最近更新 更多