[net.lang.c] Int and Char

ecf_eprm@jhunix.UUCP (Paul R Markowitz) (07/24/86)

Don't C programmers know the difference between a char and an int?
I get these great public domain programs off the net and I spend
the next 2 weeks deciding which variables are declared as char
but really mean short.  You see, it's like this.  Short, int, and
long are all SIGNED.  That means they can take on negative values.
Chars are NOT SIGNED, there is no char called -1.  If you want a
variable that takes on negative values, use a short.  It certainly
makes your code easier for others to read as well as making it
more portable.

For my next question, why doesn't my C compiler accept declarations
like 'signed char a;' or something like that?  It says 'signed undefined'
and dies.  Is there no way to make up for the errors of others
and artificially make chars come out signed?  I am running sys V rel2
on an att 3b20.  

Just had to get this off my chest.

Paul
-- 
------------------------------------------------------------------------
Paul Markowitz

"A pessimist is someone who won't call on G-d because he is certain he will
get an answering machine."

"Do you wonder if I'm really happy?            seismo!umcp-cs!jhunix!ins_aprm
 Am I just the company you keep?               bitnet: ins_aprm@jhuvms
 Which one of us excercises on the old         arpanet: ins_aprm%jhunix.BITNET@wiscvm.ARPA
   tread mill?
 Who hides his head pretending to sleep?"
-Ian Anderson (and Robert Burns?)

art@ACC.ARPA (07/25/86)

> Don't C programmers know the difference between a char and an int?
> I get these great public domain programs off the net and I spend
> the next 2 weeks deciding which variables are declared as char
> but really mean short.  You see, it's like this.  Short, int, and
> long are all SIGNED.  That means they can take on negative values.
> Chars are NOT SIGNED, there is no char called -1.  If you want a
> variable that takes on negative values, use a short.  It certainly
> makes your code easier for others to read as well as making it
> more portable.
> 
> For my next question, why doesn't my C compiler accept declarations
> like 'signed char a;' or something like that?  It says 'signed undefined'
> and dies.  Is there no way to make up for the errors of others
> and artificially make chars come out signed?  I am running sys V rel2
> on an att 3b20.  
> 
> Just had to get this off my chest.

To quote K&R 2.7:

	"There is one subtle point about the conversion of characters
	to integers.  The language does not specify whether variables
	of type char are signed or unsigned quantities.  When a char
	is converted to an int, can it ever produce a negative integer?
	Unfortunately, this varies from machine to machine, reflecting
	differences in architecture.
	...
	The definition of C quarantees that any character in the machine's
	standard character set will never be negative, so these characters
	may be used freely in expressions as positive quantities.  But
	arbitrary bit patterns stored in character variables may appear
	to be negative on some machines, yet positive on others."

MOST compilers I know of assume that chars are SIGNED and support declaration
of "unsigned char".

					<Art@ACC.ARPA>

------

chris@umcp-cs.UUCP (Chris Torek) (07/26/86)

In article <3250@jhunix.UUCP> ecf_eprm@jhunix.UUCP (Paul R Markowitz) writes:
>Chars are NOT SIGNED, there is no char called -1.

Whether characters are signed or not is compiler-dependent.  X3J11
says so; and even K&R says so (p. 40).

>If you want a variable that takes on negative values, use a short.

Or, optionally, a typedef and/or a sign-extension macro:

	/*
	 * types.h: system dependent types.
	 *
	 * Turn on the appropriate things for your system.
	 */

	/* compiler error until installer adjusts this */
	THIS FILE WAS NOT SET UP FOR YOUR SYSTEM YET!

	/* a small integer, signed */
	/* typedef char smallint; */
	/* typedef short smallint; */

	/* take a number, treat as eight bits, and sign extend */
	/* #define Sign8(c) ((int)(char)(c)) */

	/* use this one on Suns to avoid a compiler bug with constants */
	/* this also works on 32 bit machines with sign extending `>>' */
	/* #define Sign8(c) (((c) << 24) >> 24) */

	/* #define Sign8(c) ((c) & 0x80 ? (c) - 0x100 : (c)) */

Finally, for X3J11 C:

	/* typedef signed char smallint; */

	/* #define Sign8(c) ((int)(signed char)(c)) */
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

dlc@zog.cs.cmu.edu (Daryl Clevenger) (07/26/86)

I agree this is a major oversight in portability, but I think the main reason
that there is no 'signed' adjective for chars is that the representation and
interpretation for chars is too machine dependent.  That is, a machine can not
be told to interpret chars as signed if it only knows about unsigned
reprsentations.  Of course, as far as I know, any machine that uses signed
chars can interpret them as unsigned, so the 'unsigned' adjective can be
applied to chars.  Why can't everyone's machine be like a VAX :-)

guy@sun.UUCP (07/27/86)

> For my next question, why doesn't my C compiler accept declarations
> like 'signed char a;' or something like that?

Because it's not an ANSI C compiler.  The ANSI X3J11 draft includes a
"signed char" specification, but AT&T hasn't put one into the 3B20 C
compiler yet (I suspect few, if any, other PCC-based compilers have, either).
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com (or guy@sun.arpa)

guy@sun.uucp (Guy Harris) (07/27/86)

> I agree this is a major oversight in portability, but I think the main
> reason that there is no 'signed' adjective for chars is that the
> representation and interpretation for chars is too machine dependent.

The trouble with this theory is that there *is* a "signed" adjective for
"char"s in ANSI C; somebody recently claimed here that some C compiler even
implemented it.

> That is, a machine can not be told to interpret chars as signed if it only
> knows about unsigned reprsentations.

Oh, yes it can!  It may not be *convenient*, but it's certainly *possible*.
Consider the sequence

	load byte into register
	if (high-order bit of that byte == 1)
		OR in a mask of 1's to set all bits above it

You now have that "char" in the register, sign-extended.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com (or guy@sun.arpa)

bright@dataio.UUCP (07/30/86)

In article <5529@sun.uucp> guy@sun.UUCP writes:
>> For my next question, why doesn't my C compiler accept declarations
>> like 'signed char a;' or something like that?
>Because it's not an ANSI C compiler.  The ANSI X3J11 draft includes a
>"signed char" specification, but AT&T hasn't put one into the 3B20 C
>compiler yet (I suspect few, if any, other PCC-based compilers have, either).

Datalight C supports 'signed char' declarations. Datalight C is also the
only one I know of that supports 'const' and 'volatile' storage class
modifiers.