Relaxing -Wsign-compare
Frank Klemm
pfk@fuchs.offl.uni-jena.de
Thu Sep 20 12:11:00 GMT 2001
On Thu, Sep 20, 2001 at 03:45:27PM -0000, Morten Welinder wrote:
>
> IMHO, the -Wsign-compare is a bit too agressive to be really useful.
> Consider this example:
>
> -----------------------------------------------------------------------------
> struct {
> int a, b;
> } foo [] = {
> {1,2}, {3,4}
> };
>
> int
> main (int argc, char **argv)
> {
> int i;
>
> for (i = 0; i < sizeof (foo) / sizeof (foo[0]); i++)
> ;
>
> return 0;
> }
> -----------------------------------------------------------------------------
>
> > gcc-3.0 -Wsign-compare signed.c
> signed.c: In function `main':
> signed.c:12: warning: comparison between signed and unsigned
>
> A similar warning can be had with typical MIN and MAX macros when
> used with an unsigned expression and an explicit integer, say
> MAX (expr, 42).
>
> Would it be reasonable to silence this warning when one of the sides is
> a constant (in the C meaning) that fits well within the range of the
> other side's type?
>
------------------------------------------------------------------------------
16 bit integer CPU/Compiler:
char foo [32000];
int
main ( int argc, char** argv )
{
int i;
for (i = 0; i < sizeof (foo) / sizeof (foo[0]); i += 1000 )
;
return 0;
}
------------------------------------------------------------------------------
BTW the right coding is:
char foo [32000];
int
main ( int argc, char** argv )
{
size_t i;
for (i = 0; i < sizeof (foo) / sizeof (foo[0]); i += 1000 )
;
return 0;
}
This will also works correctly in 2010 in the following context:
char foo [4_700_000_000]; // small buffer or memory-mapped DVD
int
main ( int argc, char** argv )
{
size_t i;
for (i = 0; i < sizeof (foo) / sizeof (foo[0]); i += 1000 )
;
return 0;
}
--------------------------------------------------------------------------------
The main problem I have with signed vs. unsigned are normal strings.
In Germany we have so called modified vowels, also other languages have
modified letters. These are part of ISO-646 aka ISO-8859-1. But it is
necessary to use 'unsigned char' for characters (otherwise you tap a rich
pool of errors):
const unsigned char* text = "Erdbärtörtchen";
When you are using strcmp(), it complains about sign issue:
const unsigned char* cmpstr = "Eichhörnchenpfötchen";
if (strcmp ( text, cmpstr )) {
...
}
x.c:3: warning: pointer targets in initialization differ in signedness
x.c:6: warning: pointer targets in initialization differ in signedness
x.c: In function
ain':
x.c:10: warning: pointer targets in passing arg 1 of trcmp' differ in signedness
x.c:10: warning: pointer targets in passing arg 2 of trcmp' differ in signedness
The really strange thing is that strcmp() works with unsigned char inside:
#include <stdio.h>
#include <string.h>
const unsigned char* text = "Erdbärtörtchen";
const unsigned char* cmpstr = "Eichhörnchenpfötchen";
int main ( void )
{
int cmp;
if (0 == strcmp ( text, cmpstr )) {
fprintf (stderr, "Bug!\n");
}
cmp = strcmp ("Hase", "Häsin");
if (cmp < 0)
fprintf (stderr, "'Hase' < 'Häsin', i.e. compares 'unsigned char*'\n");
if (cmp > 0)
fprintf (stderr, "'Hase' > 'Häsin', i.e. compares 'signed char*'\n");
return 0;
}
x.c:4: warning: pointer targets in initialization differ in signedness
x.c:5: warning: pointer targets in initialization differ in signedness
x.c: In function
ain':
x.c:10: warning: pointer targets in passing arg 1 of trcmp' differ in signedness
x.c:10: warning: pointer targets in passing arg 2 of trcmp' differ in signedness
---------------------------------------------------------------------------------
With C you only need to ignore the warnings, with C++ it becomes a painful.
Normally I work in the way only using 'signed char' and casting en masse.
National languages and C strings is something ...
---------------------------------------------------------------------------------
Frank Klemm
More information about the Gcc
mailing list