Subject: GCC bug? feature? char is unsigned

From: zhu qun ying <[email-masked]>
Date: Fri, 12 May 2000 16:26:01 +0800

Hi,

I am in the progress of porting a program to StrongARM, and has encounter the
following error. This simple error give us a big headache to trace it down.

consider this simple program:
int
main(void)
{
    char i = -1;
    printf("%d\n", i);
    return 0;
}

The print out is 255 in stead of -1, unless I define i as
signed char i;
then I get the "-1" print out.

I know the compiler is free to implement char as signed or unsigned or "pseudo
unsigned" according to the standard. But as gcc is treating char as signed char
for other platforms, I wonder is this a special treatment for StronARM? Is it a
bug in GCC? Or my assumsion of gcc will treat char as signed for all platform is
simply wrong. Should it behaves consistently across platforms?

I am using the pre-build cross compiler from LART projects.

-- 
 (~._.~)  Öì Èº Ó¢  (Qun Ying)         (65) 874-6743
  ( O )         Kent Ridge Digital Labs (KRDL)
 ()~*~()  21 Heng Mui Keng Terrace, Singapore 119613
 (_)-(_)    [email-masked]  *  [email-masked]

unsubscribe: body of `unsubscribe linux-arm' to [email-masked]
++        Please use [email-masked] for           ++
++                        kernel-related discussions.                      ++

---

From: Erik Mouw <[email-masked]>
Date: Fri May 12 10:59:16 +0200 (MDT) 2000

> then I get the "-1" print out.

You do know how to get in trouble... ;-)

> bug in GCC? Or my assumsion of gcc will treat char as signed for all platform
> is simply wrong. Should it behaves consistently across platforms?

No. This is the output on an SGI Onyx2 (Mips R12000 CPU) running IRIX 6.5 with
gcc 2.95.2 as compiler:

  erik@lumiere:/tmp >uname -a
  IRIX64 lumiere 6.5 10181058 IP27
  erik@lumiere:/tmp >gcc --version
  2.95.2
  erik@lumiere:/tmp >gcc -Wall -o foo foo.c
  foo.c: In function `main':
  foo.c:5: warning: implicit declaration of function `printf'
  erik@lumiere:/tmp >./foo 
  255

AFAIK as I know gcc is compliant with the platform's native compiler, not
with itself.

PLEASE don't send followups to the LART list because it is completely
off-topic on that list.

Erik

-- 
J.A.K. (Erik) Mouw, Information and Communication Theory Group, Department
of Electrical Engineering, Faculty of Information Technology and Systems,
Delft University of Technology, PO BOX 5031,  2600 GA Delft, The Netherlands
Phone: +31-15-2783635  Fax: +31-15-2781843  Email: [email-masked]
WWW: http://www-ict.its.tudelft.nl/~erik/

---

From: zhu qun ying <[email-masked]>
Date: Fri, 12 May 2000 18:56:46 +0800

> You do know how to get in trouble... ;-)

Ya. I learned my programming under x86 arch., so there are some assumsions are
made without noticed until I caught an error then trace into the problem ...
like this one. I should say it is due to my bad programming practices ...

> PLEASE don't send followups to the LART list because it is completely

At least this teach me a lesson. Thanks for your help. And sorry for the cross
posting on LART list. I was thinking it may be related to some extend. ...

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Fri, 12 May 2000 11:25:37 +0100 (BST)

> then I get the "-1" print out.

Your code is buggy.  I am trying to get a warning put into GCC for this type of
thing.  However, the GCC mailing address seems to be rather non-responsive.
GCC will complain about things like:

	{
		char foo;

		foo = bar();

		if (foo == -1) {
			...
		}
	}

Things to generally look out for in programs (in the following fragments, c is
declared as "char"):

	Code			Correction
	----			----------
1.	c = getopt()		c should be declared as "int"
2.	c = getc()		c should be declared as "int"
3.	c == EOF		c should be declared as "int"
4.	c < 0			c should be declared as "signed char" or "int"

1) getopt() is defined as returning an "int" not a "char"
2) getc() is defined as returning an "int" not a "char"
3) EOF is a "negative integral constant"
4) this is ambiguous and examination of the surrounding code should indicate which
   case is more correct.  However, "int" is the perferred, unless the code is
   relying on some characteristic of "signed char".

Nos 1, 2 and 3 can cause problems even in a signed char environment.  Take the
instance of a file containing a byte value 0xff.

I'll put this up as a FAQ...

> unsigned" according to the standard.

Replace "the compiler" with "the compiler for a particular platform".

> But as gcc is treating char as signed char for other platforms, I wonder is
> this a special treatment for StronARM?

It generates faster, more efficient code.

> Is it a bug in GCC?

No.

> Or my assumsion of gcc will treat char as signed for all platform is
> simply wrong.

Yes.

> Should it behaves consistently across platforms?

No.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |            http://www.arm.linux.org.uk/            /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |

---

From: Paul Koning <[email-masked]>
Date: Fri, 12 May 2000 11:31:01 -0400 (EDT)

>>>>> "zhu" == zhu qun ying <[email-masked]> writes:

 zhu>...
 zhu> I know the compiler is free to implement char as signed or
 zhu> unsigned or "pseudo unsigned" according to the standard. But as
 zhu> gcc is treating char as signed char for other platforms, I
 zhu> wonder is this a special treatment for StronARM? Is it a bug in
 zhu> GCC? Or my assumsion of gcc will treat char as signed for all
 zhu> platform is simply wrong. Should it behaves consistently across
 zhu> platforms?

No.  The compiler is perfectly well entitled to do it differently for
different platforms.

If you say "char" in your program, you're telling the compiler that it
doesn't matter whether it is signed or unsigned.  If it does matter,
then you *must* write "signed char" or "unsigned char".  If you don't
do that, it's a bug in your code...

   paul

---

From: Philip Blundell <[email-masked]>
Date: Fri, 12 May 2000 19:30:18 +0100

>Or my assumsion of gcc will treat char as signed for all platform is

Unfortunately this is the case.

>Should it behaves consistently across platforms?

No.  RS6000 has `char' unsigned by default as well.  You can use 
-fsigned-char to force the other behaviour, but there will be a performance 
hit if you do this.  It's usually better to fix the code.

p.

---

From: Kira Brown <[email-masked]>
Date: Fri, 12 May 2000 19:08:08 +0100 (BST)

> hit if you do this.  It's usually better to fix the code.

Surely if signedness is important for a char (and it usually isn't), you
can use a signed char?

kira.

---

From: Philip Blundell <[email-masked]>
Date: Fri, 12 May 2000 20:27:07 +0100

>Surely if signedness is important for a char (and it usually isn't), you

Yes, of course.  The -fsigned-char option is useful if you have large amounts 
of dusty-deck code with this problem and want a quick fix to get it working, 
but it is definitely not a good solution in general.

p.