【问题标题】:warning: comparison of unsigned expression >= 0 is always true警告:无符号表达式的比较 >= 0 始终为真
【发布时间】:2013-11-19 14:24:20
【问题描述】:

编译C文件时出现如下错误:

t_memmove.c: In function ‘ft_memmove’:
ft_memmove.c:19: warning: comparison of unsigned expression >= 0 is always true

这是完整的代码,来自cat ft_memmove.c

#include "libft.h"
#include <string.h>

void    *ft_memmove(void *s1, const void *s2, size_t n)
{
    char    *s1c;
    char    *s2c;
    size_t  i;

    if (!s1 || !s2 || !n)
    {
        return s1;
    }
    i = 0;
    s1c = (char *) s1;
    s2c = (char *) s2;
    if (s1c > s2c)
    {
        while (n - i >= 0) // this triggers the error
        {
            s1c[n - i] = s2c[n - i];
            ++i;
        }
    }
    else
    {
        while (i < n)
        {
            s1c[i] = s2c[i];
            ++i;
        }
    }
    return s1;
}

我确实知道 size_t 是无符号的,因此两个整数都将 >= 0。但是因为我是从另一个中减去一个,所以我不明白。为什么会出现这个错误?

【问题讨论】:

  • 两个无符号整数的算术运算结果也是一个无符号整数,因此根据定义大于或等于零。如果在您的示例中i 大于n,则减法的结果将“换行”为(大)正数。您可能应该检查n &gt;= i

标签: c gcc


【解决方案1】:

如果你在 C 中减去两个无符号整数,结果将被解释为无符号。它不会因为您减去它而自动将其视为已签名。解决此问题的一种方法是使用n &gt;= i 而不是n - i &gt;= 0

【讨论】:

    【解决方案2】:

    考虑这个循环:

    for(unsigned int i=5;i>=0;i--)
    {
    
    }
    

    这个循环将是无限的,因为每当 i 变为 -1 时,它将被解释为一个非常大的正值,因为 unsigned int 中不存在符号位。

    这就是此处生成警告的原因

    【讨论】:

    • 我遇到了问题。任何参考解释这个问题?但printf 中的输出仍然是负数,如 -1 等。
    • 我已经解决了我的问题:unsigned int i,j;for (j=6,i=j-1;j&gt;0;j--,i=j-1){}。我的回答here.
    【解决方案3】:

    根据草案 C99 标准的6.3.1.8 部分通常的算术转换,因为它们都是相同的类型,所以结果也将是size_t。该部分指出:

    [...]除非另有明确说明,普通实数类型也是结果对应的实数类型[...]

    后来又说:

    如果两个操作数的类型相同,则不需要进一步转换。

    从数学上讲,您可以像这样将i 移动到表达式的另一侧:

     n >= i
    

    【讨论】:

      【解决方案4】:

      unsigned 的算术运算结果为 unsigned,这就是您收到此警告的原因。最好将n - i &gt;= 0 更改为n &gt;= i

      【讨论】:

        【解决方案5】:

        带有无符号操作数的操作在无符号类型的域中执行。无符号算术遵循模算术规则。这意味着结果将永远为负,即使您从某事中减去某事。例如1u - 5u 不会产生-4。如果产生UINT_MAX - 3,这是一个与-4UINT_MAX + 1 一致的巨大正值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-11-11
          • 2011-04-09
          • 1970-01-01
          • 1970-01-01
          • 2017-08-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多