This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Signedness of wchar_t and wint_t leads to problems with gcc -Wsign-conversion


I was looking at a Debian bug report[1] that left me puzzled on a
certain point. At the very least, I want to document a solution to the
reporter's (Igor) problem, but I wonder also if there is an
implementation bug.

The issue concerns iwslower() and simialr functions that take a wint_t argument:

     int iswlower(wint_t wc);

Suppose that the argument to be passed is a 'wchar_t' (as is common,
AFAIK). If one compiles with

    gcc -Wsign-conversion

then the following warning results:

warning: conversion to ‘wint_t {aka unsigned int}’ from ‘wchar_t {aka
int}’ may change the sign of the result [-Wsign-conversion]

What should one do to remove this warning?

There is an analogous situation with islower() and similar functions,
where the solution is described by an update I recently added for the
upcoming man-pages release:

       The standards require that the argument c for these  functions  is
       either  EOF  or a value that is representable in the type unsigned
       char.  If the argument c is of type  char,  it  must  be  cast  to
       unsigned char, as in the following example:

           char c;
           ...
           res = toupper((unsigned char) c);

       This  is  necessary  because  char may be the equivalent of signed
       char, in which case a byte where the top bit is set would be  sign
       extended  when converting to int, yielding a value that is outside
       the range of unsigned char.

However, we don't have a similar solution for iswlower(), because
there is no "(unsigned wchar_t)" cast. And casting to (wint_t) seems
incorrect to me, because if wchar_t is a signed type smaller than
wint_t, then sign extension could occur. (POSIX allows wint_t and
wchar_t to be either signed or unsigned integer types.)

I could be wrong, but it seems like an implementation bug that one of
these types is signed and the other is unsigned. (My brief inspection
of some other systems suggests that on those systems, wchar_t and
wint_t have the same signedness.)

Anyone have any insights here, or did I miss something obvious?

Cheers,

Michael


[1] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=845172
-- 
Michael Kerrisk
Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/
Linux/UNIX System Programming Training: http://man7.org/training/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]