问题
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?
回答1:
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! :)
回答2:
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.
回答3:
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 .
来源:https://stackoverflow.com/questions/2771538/why-doesnt-gcc-produce-a-warning-when-assigning-a-signed-literal-to-an-unsigned