[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: at least 260 packages broken on arm, powerpc and s390 due to wrong assumption on char signedness

Ganesan R writes:
> On Mon, Dec 31, 2001 at 01:33:37PM -0500, Colin Walters wrote:

>> It can't be larger than 255 (precisely because it is limited to a single
>> byte).

>> The more I think about it, the more it makes sense to always explicitly
>> declare all char variables as signed or unsigned; otherwise, you're just
>> asking for latent bugs.

Do remember that people port to systems other than Linux with gcc.
IIRC 'signed char' is not available in pre-ANSI C.  Code that was
written to be compilable on those platforms will use plain char and
extra checks.  For such code, these 'comparison is always {true|false}
due to limited range of datatype' messages are just annoying.

For portability the general rule is that _if_ you can get away with
using plain 'char', you should.

> This works only as long as you own all of your code. The problem is you can
> assign signed char to unsigned char or vice versa without any ill effects;
> you won't even get a compiler warning. However, the same can't be said for
> signed char * vs unsigned char *. If you are interfacing to external code
> (even functions like strcpy etc), you are asking for a major type casting
> headache. Worse, the problem won't even show up if you are developing on the
> "right" platform. I've gone down that route once and then gave up :-(. 

C++ is interesting in that regard, as it treats 'char', 'signed char',
and 'unsigned char' as three different types.  If you want to the C
string handling functions, you'll have to use 'char*' for strings, or
implement a workaround.

> Another thing that puzzles me since this whole debate started. If you look
> at the declaration of ctype.h functions (isalpha family), they take a int as
> an argument. The man page explicitly mentions the argument should be an
> unsigned char - obvious because a signed char would sign extend to an int.
> For platforms that default to signed char, and it appears majority of them
> do, you need to cast a "default" char type before calling ctype functions.
> Still, I have not seen any code that does it.

For this reason, implementations of the isalpha family tend to work
around the problem of being given negative-valued char arguments.  So
you get code like this in libc's ctype.h:

        extern __inline int
        tolower (int __c) __THROW
          return __c >= -128 && __c < 256 ? __ctype_tolower[__c] : __c;

As result, faulty code sort-of works, and therefore never gets fixed.

Olaf Weber

               (This space left blank for technical reasons.)

Reply to: