Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I fix warnings like: "comparison between signed and unsigned"?

Tags:

c

I have been advised to use the following options with GCC, as it helps to avoid a lot of common errors. It turns on a bunch of warnings and -Werror turns them into errors.

gcc -pedantic -W -Wall -Wextra -Wshadow -Wstrict-overflow=5 -Wwrite-strings -std=c99 -Werror

Given the following test code:

#include <stdio.h>

int main(void)
{
    int arr[8]={0,10,20,30,40,50,60,70};
    int x;

    printf("sizeof(arr): %d\n", sizeof(arr));
    printf("sizeof(int): %d\n", sizeof(int));

    for(x = 0; x < sizeof(arr)/sizeof(int); x++)
    {
        printf("%d\n",arr[x]);
    }

    return 0;
}

I get this:

test.c:11: error: comparison between signed and unsigned

I know that one way I can fix this is turning off the warnings, but they haven't made me use these settings to turn them off in the end.

Another way is to cast the stuff, but I have been told that casting is deprecated.

Also, I could make x into an unsigned int:

unsigned x;

But it doesn't solve the general problem when I have to compare signed values with unsigned values using these compiler options. Is there an cleaner way instead of casting?

like image 409
George Avatar asked May 13 '09 19:05

George


People also ask

How can you tell the difference between signed and unsigned integers?

A signed integer is a 32-bit datum that encodes an integer in the range [-2147483648 to 2147483647]. An unsigned integer is a 32-bit datum that encodes a nonnegative integer in the range [0 to 4294967295]. The signed integer is represented in twos complement notation.

How do I turn off Wsign comparison?

Type in -Wno-sign-compare The warning -Wsign-compare can be negated by adding "-Wno" as a prefix. In fact warnings can be ignored by adding -Wno- to the warning code.

Is it suggested to compare signed and unsigned numbers in C++?

Sure, comparisons between signed and unsigned would be slower, but their result would be more correct in some sense. @Nawaz Your bottom line conclusion is incorrect, unfortunately: if the signed type can contain the unsigned type, the unsigned will be converted to the signed type and not the opposite.

Can we compare signed and unsigned int in C?

The hardware is designed to compare signed to signed and unsigned to unsigned. If you want the arithmetic result, convert the unsigned value to a larger signed type first. Otherwise the compiler wil assume that the comparison is really between unsigned values. And -1 is represented as 1111..


2 Answers

This really depends on the data type. It is possible to avoid this by implicitly casting the values to a type which contains a superset of all the values available in the signed and unsigned type. For instance you could use a 64 bit signed value to compare an unsigned 32 bit and a signed 32 bit value.

However this is a corner case and you need to do operations like verify the size of your types. Your best solution is to use the same type for both operands.

If you must cast, do consider that you could be causing an overflow and consider if that is important to your application or not.

like image 24
JaredPar Avatar answered Oct 14 '22 17:10

JaredPar


Replace

int x;
/* ... */
for(x=0;x<sizeof(arr) / sizeof(int);x++)

by

for(size_t x=0;x<sizeof(arr) / sizeof(int);x++)

But it doesn't solve the general problem when I have to compare signed values with unsigned values using these compiler options. Is there an cleaner way insted of casting?

In such cases, try to figure out if the signed number can ever have a value which will cause overflow. If not, you can ignore the warning. Otherwise a cast to the unsigned type (if this is the same size or bigger than the signed component) is good enough.

like image 155
dirkgently Avatar answered Oct 14 '22 16:10

dirkgently