Subject: Is char signed or unsigned ?

From: Zsolt Kiraly <[email-masked]>
Date: Thu, 04 Mar 1999 15:38:23 -0800

Hi Russell, Phil,

I figured out why the termios program did not work on the Brutus. It was
not related to termios stuff, rather how chars might not be the same on
the PC as on the brutus.

In this code there is a function (int foo())that returns an int. But the
return value is assigned to a char:

char c;
c = foo();

if (c >= 0) 

The arm-linux-gcc (egcs-1.1.1 with your patch + glibc-2.1) warns me that
this will always be true, due to limited range of the variable. The
native PC compiler (gcc-2.7.2.3, glibc 2.0.7) does not complain. The PC
version works flawlessly, the arm version probably assigns 0 to c.

Later in the code:

if (c < 0)

Same warning (will never be true) with the arm gcc, no warning with the
native gcc.

Workaround:

int temp_c;

temp_c = foo();

c = (char)temp_c; //so I can compare it as a char

if (c >= 0)
.
.
.
if (temp_c < 0) // because c apperantly does not go < 0

So, I guess the gcc-2.7.2.3 does automatic typecasting, the cross-egcs
does not ? And the native char seems to be signed, while the cross-char
unsigned ? I wonder what the ANSI C docs say about this.

Anyway, I thought you might like to know about this. Maybe gcc-2.7 is
out of spec, I don't know.

The code is the robin.c program from Erik Troan's Linux Applications
Development book, and the first warning was line 193, the second at line
220.

After the above modifications the code compiles without errors or
warnings, and runs on the Brutus (yeee!!!!!!!). Also on the PC.

Later,

Zsolt
[email-masked]
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Philip Blundell <[email-masked]>
Date: Fri, 05 Mar 1999 09:22:27 +0000

>unsigned ? I wonder what the ANSI C docs say about this.

ISO C allows char to be either signed or unsigned by default.  On the ARM it 
is unsigned because zero-extension is so much faster than sign extension.

You can override this with the -fsigned-char option to gcc.  I think RPM does 
this by default.

In the case you quoted the code is at fault and the compiler is correct.  

p.

---

From: Russell King <[email-masked]>
Date: Fri, 5 Mar 1999 09:26:17 +0000 (GMT)

> version works flawlessly, the arm version probably assigns 0 to c.

IMHO, this is very bad programming practice.  For example, if you're using
getc(), and you're reading characters from a binary file with the following
code:

  char c;
  do {
     c = getc(file);
     ...
  } while (c != EOF);

What happens if the file contains 0xff?  The variable that is used
to hold the return value of getc, getopt and so forth should always be
an int.  Basically, the problem comes down to a loss of information.
Should you really use a char to old a return value of the size of an
int, and expect to be able to check for values of the int using a char?

> c = (char)temp_c; //so I can compare it as a char

This should also be:
  if (temp_c >= 0)

> unsigned ? I wonder what the ANSI C docs say about this.

The native char is unsigned.  It produces better code to have it
unsigned, since you don't have to have two extra instructions after
every load (to convert the unsigned load to a signed value).

> Development book, and the first warning was line 193, the second at line

Most people don't seem to be aware of this issue, because the PC is
what it is.

> warnings, and runs on the Brutus (yeee!!!!!!!). Also on the PC.

I have a lot of patches on my FTP site for various programs which suffer
from this problem.

--
Russell King ([email-masked])

---

From: "Dr. David Alan Gilbert" <[email-masked]>
Date: Fri, 05 Mar 1999 09:45:46 +0000

> unsigned ? I wonder what the ANSI C docs say about this.

ANSI says that the signedness of char is implementation defined.
ARM systems tend to use unsigned char because an ldrb works as a good
unsigned char load; where as if you wanted to sign extend you can only
do that on newer ARMs.

Doesn't gcc have a flag to specify the signedness?

> Development book, and the first warning was line 193, the second at line

Its a bug in the code - he should be using signed char if he intends
to do wacky comparisons with it.

Dave