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