How Do I Fix comparison between signed and unsigned integer expressions

I get this warning when i try to run my program:
 
warning: comparison between signed and unsigned integer expressions [-Wsign-compare]


This is the part of the code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
for(int i = 0 ; i < n-1 ; i++)
    {
        for(int j = i+1 ; j < n ; j++)
        {
            if(inputArr[i] == inputArr[j])
            {
                onlist=false;
                for(int k =0; k<list.size(); k++)
                {
                    if(inputArr[i]==list[k])
                    {
                        onlist=true;
                    }
                }
                if(!onlist)
                {
                    list.push_back(inputArr[i]);
                }
            }
        }
    }

A warning like what you are getting is not something seen at run-time, only at compile-time. So which comparison is vomiting up the warning?

You don't really provide enough code for anyone to make an educated guess as to what the issue might be, nor give a clue where the warning is.

Partial code is useless.
size() functions return std::size_t type which is unsigned.

Change for loops to :

for(std::size_t k =0; k<list.size(); k++)

Even better use a range based for loop if iterating through the whole container.
The problem is that comparisons with signed and unsigned integers (where the unsigned type is not smaller than the signed type and not smaller than int) will lead to the signed type being converted to the unsigned type before the comparison takes place. This leads to problems if the signed integer variable can be negative.

Example:
1
2
3
4
5
6
7
8
9
10
11
unsigned int uint = 0;
signed int sint = -1;

if (sint < uint)
{
	std::cout << sint << " is less than " << uint << ".\n";
}
else
{
	std::cout << sint << " is greater than or equal to " << uint << ".\n";
}

The example above will print "-1 is greater than or equal to 0." which is clearly not what one would expect. The reason is because sint is automatically converted to an unsigned int (same type as uint) before being compared, and converting a negative signed value to an unsigned type ends up with a very big positive value.

This is not really a problem in the code that you posted because values are never negative but it is still a useful warning to have, I wouldn't disable it and I wouldn't ignore it, so a way around this is to use std::size_t (or some other unsigned integer type) for the indices when looping over a container.

Another approach that some prefer is to convert the size to a signed type before doing anything with it. This could be done using an explicit cast or a helper function such as std::ssize which was introduced in C++20 (before that you could easily write such a helper function yourself).
Last edited on
Topic archived. No new replies allowed.