conradkleinespel
conradkleinespel

Reputation: 6987

warning: comparison of unsigned expression >= 0 is always true

I have the following error when compiling a C file:

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

Here's the full code, via 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;
}

I do understand that size_t is unsigned and that both integers will be >= 0 because of that. But since I'm subtracting one from the other, I don't get it. Why does this error come up?

Upvotes: 5

Views: 14865

Answers (5)

deeiip
deeiip

Reputation: 3379

consider this loop:

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

}

This loop will be infinite because whenever i becomes -1 it'll be interprated as a very large possitive value as sign bit is absent in unsigned int.

This is the reason a warning is generated here

Upvotes: 3

Shafik Yaghmour
Shafik Yaghmour

Reputation: 158469

According to section 6.3.1.8 of the draft C99 standard Usual arithmetic conversions, since they are both of the same type, the result will also be size_t. The section states:

[...]Unless explicitly stated otherwise, the common real type is also the corresponding real type of the result[...]

and later on says:

If both operands have the same type, then no further conversion is needed.

mathematically you can just move the i over to the other side of the expression like so:

 n >= i

Upvotes: 2

AnT stands with Russia
AnT stands with Russia

Reputation: 320401

Operations with unsigned operands are performed in the domain of unsigned type. Unsigned arithmetic follows the rules of modular arithmetic. This means that the result will never be negative, even if you are subtracting something from something. For example 1u - 5u does not produce -4. If produces UINT_MAX - 3, which is a huge positive value congruent to -4 modulo UINT_MAX + 1.

Upvotes: 0

haccks
haccks

Reputation: 106012

Arithmetic on unsigned results in an unsigned and that's why you are getting this warning. Better to change n - i >= 0 to n >= i.

Upvotes: 0

lurker
lurker

Reputation: 58244

If you subtract two unsigned integers in C, the result will be interpreted as unsigned. It doesn't automatically treat it as signed just because you subtracted. One way to fix that is use n >= i instead of n - i >= 0.

Upvotes: 21

Related Questions