Why doesn't GCC produce a warning when assigni

2019-02-12 10:32发布

Several questions on this website reveal pitfalls when mixing signed and unsigned types and most compilers seem to do a good job about generating warnings of this type. However, GCC doesn't seem to care when assigning a signed constant to an unsigned type! Consider the following program:

/* foo.c */
#include <stdio.h>
int main(void)
{
    unsigned int x=20, y=-30;
    if (x > y) {
        printf("%d > %d\n", x, y);
    } else {
        printf("%d <= %d\n", x, y);
    }
    return 0;
}

Compilation with GCC 4.2.1 as below produces no output on the console:

gcc -Werror -Wall -Wextra -pedantic foo.c -o foo

The resulting executable generates the following output:

$ ./foo
20 <= -30

Is there some reason that GCC doesn't generate any warning or error message when assigning the signed value -30 to the unsigned integer variable y?

3条回答
爷、活的狠高调
2楼-- · 2019-02-12 11:00

Using (unsigned)-1 is an often used way to set all bits and sometimes even quoted as reason for this (mis)feature of C, even by people who should know better . It's neither obvious nor portable -- the expression you want to use to set all bits is ~0 .

查看更多
贼婆χ
3楼-- · 2019-02-12 11:04

Use -Wconversion:

~/src> gcc -Wconversion -Werror -Wall -Wextra -pedantic -o signwarn signwarn.c
cc1: warnings being treated as errors
signwarn.c: In function 'main':
signwarn.c:5: error: negative integer implicitly converted to unsigned type

I guess the thing here is that gcc is actually pretty good at generating warnings, but it defaults to not doing so for (sometimes unexpected) cases. It's a good idea to browse through the available warnings and choose a set of options that generate those you feel would help. Or just all of them, and polish that code until it shines! :)

查看更多
姐就是有狂的资本
4楼-- · 2019-02-12 11:05

The ability to convert negative value to unsigned type is a feature of C language. For this reason, the warning is not issued by default. You have to request it explicitly, if you so desire.

As for what your program outputs... Using %d format specifier of printf with an unsigned value that lies beyond the range of type int results in undefined behavior, which is what you really observed in your experiment.

查看更多
登录 后发表回答