[comp.lang.c] Conversions/casts one more time

wendyt@unisoft.UUCP (Wendy Thrash) (12/09/86)

(Sorry if this has been asked before; my memory is sometimes [unsigned] short.)

When I compile and run the program below, I expect to get the same answer
three times.  On our 11/750 under 4.3 BSD, I get
	c = ffffffaa, (char)uc = ffffffaa, (char)ucf() = aa
Seems to me that I ought to get ffffffaa for all three.

Questions:
1) Am I missing something, or did the BSD compiler just drop a conversion?
2) Is this sort of thing supposed to be implementation dependent?
3) My July '86 version of the X3J11 draft says (in 3.3.4), "A cast that
   specifies an implicit conversion or no conversion has no effect on the
   type or value of an expression."  What the heck does that mean, really?
   Does it have anything to do with questions 1) and 2)?

----
unsigned char ucf() { return 0xaa; }

main() {
	char c;
	unsigned char uc = 0xaa;

	c = uc;
	printf("\tc = %x, (char)uc = %x, (char)ucf() = %x\n",
	  c, (char)uc, (char)ucf());
}
----
Wendy Thrash -- UniSoft Corporation
{ucbvax,lll-lcc,sun}!unisoft!wendyt

stuart@bms-at.UUCP (12/11/86)

In article <176@unisoft.UUCP>, wendyt@unisoft.UUCP (Wendy Thrash) writes:

> 	printf("\tc = %x, (char)uc = %x, (char)ucf() = %x\n",
> 	  c, (char)uc, (char)ucf());

	results in:

> 	c = ffffffaa, (char)uc = ffffffaa, (char)ucf() = aa

The compiler is broken and left out a cast.  The values printed should
all be the same, either as shown or 'aa' depending on whether 'char's
are signed or unsigned.

As to whether this is required by the X3J11 draft, I couldn't say.
(I hope not.)
-- 
Stuart D. Gathman	<..!seismo!dgis!bms-at!stuart>

adam@mtund.UUCP (12/11/86)

> (Sorry if this has been asked before; my memory is sometimes [unsigned] short.)
> 
> When I compile and run the program below, I expect to get the same answer
> three times.  On our 11/750 under 4.3 BSD, I get
> 	c = ffffffaa, (char)uc = ffffffaa, (char)ucf() = aa
> Seems to me that I ought to get ffffffaa for all three.
> 
> Questions:
> 1) Am I missing something, or did the BSD compiler just drop a conversion?
> 2) Is this sort of thing supposed to be implementation dependent?
> 3) My July '86 version of the X3J11 draft says (in 3.3.4), "A cast that
>    specifies an implicit conversion or no conversion has no effect on the
>    type or value of an expression."  What the heck does that mean, really?
>    Does it have anything to do with questions 1) and 2)?
> 
> ----
> unsigned char ucf() { return 0xaa; }
> 
> main() {
> 	char c;
> 	unsigned char uc = 0xaa;
> 
> 	c = uc;
> 	printf("\tc = %x, (char)uc = %x, (char)ucf() = %x\n",
> 	  c, (char)uc, (char)ucf());
> }
> ----
> Wendy Thrash -- UniSoft Corporation
> {ucbvax,lll-lcc,sun}!unisoft!wendyt

Ugh. %x expects an int, so the result of feeding it a char is,
*and ought to be*, UNDEFINED.
				Adam Reed (mtund!adam)

levy@ttrdc.UUCP (12/12/86)

In article <820@mtund.UUCP>, adam@mtund.UUCP writes:
>Ugh. %x expects an int, so the result of feeding it a char is,
>*and ought to be*, UNDEFINED.
>				Adam Reed (mtund!adam)

In principle, yes; in practice all C compilers I've seen (what does the
latest ANSI std. say?) convert chars to ints when passing them as arguments.
-- 
 -------------------------------    Disclaimer:  The views contained herein are
|            dan levy            |  my own and are not at all those of my em-
|         an engihacker @        |  ployer or the administrator of any computer
| at&t computer systems division |  upon which I may hack.
|        skokie, illinois        |
 --------------------------------   Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
                                        allegra,ulysses,vax135}!ttrdc!levy

wendyt@unisoft.UUCP (Wendy Thrash) (12/13/86)

Keywords:


My program:
>> unsigned char ucf() { return 0xaa; }
>> 
>> main() {
>> 	char c;
>> 	unsigned char uc = 0xaa;
>> 
>> 	c = uc;
>> 	printf("\tc = %x, (char)uc = %x, (char)ucf() = %x\n",
>> 	  c, (char)uc, (char)ucf());
>> }

Adam Reed (mtund!adam) writes:
>Ugh. %x expects an int, so the result of feeding it a char is,
>*and ought to be*, UNDEFINED.

Golly!  Guess they've changed the language on me again.  Last I heard,
char variables were converted to int whan passed as parameters.  That meant
that when I did something like this I could see what the compiler produced
when it converted the expression to int.  Guess I'll have to go back to writing
	int i, j, k;
	...
	i = c;
	j = (char)uc;
	k = (char)ucf();
and looking at the result with adb.  It's SO hard to keep up with these things!

In case anyone wonders, the point of this question was that the 4.3 VAX C
compiler sometimes throws away casts when it's doing promotions.  I don't
believe this is correct, and those who have addressed that issue (by mail as
well as by posting) have agreed.  Thanks to all of you who wrote.

chris@mimsy.UUCP (Chris Torek) (12/13/86)

>> 	printf("\tc = %x, (char)uc = %x, (char)ucf() = %x\n",
>> 	  c, (char)uc, (char)ucf());

In article <820@mtund.UUCP> adam@mtund.UUCP (Adam V. Reed) writes:
>Ugh. %x expects an int, so the result of feeding it a char is,
>*and ought to be*, UNDEFINED.

printf is also a function, so it is not possible to hand it a char.
`char' exists only as a data type (lvalue), not as an expression
type (rvalue), so `printf("%x", (char)c);' sends printf (int)(char)c,
not (char)c.

As to the original question, a cast is (supposed to be) equivalent
to an assignment to a temporary variable of the given type.  The
printf() call above is therefore (supposed to be) equivalent to

	char t1, t2;

	t1 = uc;
	t2 = ucf();
	printf("\tc = %x, (char)uc = %x, (char)ucf() = %x\n",
		c, t1, t2);

Whether this sign extends 0xaa is machine, and sometimes compiler,
dependent.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
UUCP:	seismo!mimsy!chris	ARPA/CSNet:	chris@mimsy.umd.edu

mark@ems.UUCP (Mark H. Colburn) (12/14/86)

>Adam Reed (mtund!adam) writes:
>
>Golly!  Guess they've changed the language on me again.  Last I heard,
>char variables were converted to int whan passed as parameters.  

I thought that K&R stated that type coersions did not occur when values were
passed as parameters to a function.  If the compiler did do the coersion then
it would have to keep track of the type of parameter that is exepected to be
passed to the function, even though it may be in a different file, etc.
You start talking about PASCAL...

Anyways, I cannot refer to the specific page in K&R, somebody has snatched
my copy.


-- 
Mark H. Colburn             UUCP: ihnp4!meccts!ems!mark
EMS/McGraw-Hill              ATT: (612) 829-8200
9855 West 78th Street
Eden Prairie, MN  55344

stuart@bms-at.UUCP (Stuart D. Gathman) (12/15/86)

In article <820@mtund.UUCP>, adam@mtund.UUCP (Adam V. Reed) writes:

> > 	printf("\tc = %x, (char)uc = %x, (char)ucf() = %x\n",
> > 	  c, (char)uc, (char)ucf());

> Ugh. %x expects an int, so the result of feeding it a char is,
> *and ought to be*, UNDEFINED.

Except that function arguments of short and char are automatically
converted to type int except possibly when a function prototype is
given and it is not a variable argument.  (Whew!)  All three arguments
are (or should) be implicitly cast to int.  In this case, the compiler
thought that the last char was unsigned presumably because of the
function declaration.
-- 
Stuart D. Gathman	<..!seismo!dgis!bms-at!stuart>

ballou@brahms (Kenneth R. Ballou) (12/15/86)

In article <91@ems.UUCP> mark@ems.UUCP (Mark H. Colburn) writes:
>I thought that K&R stated that type coersions did not occur when values were
>passed as parameters to a function.  If the compiler did do the coersion then
>it would have to keep track of the type of parameter that is exepected to be
>passed to the function, even though it may be in a different file, etc.

This is not true.  Note that the parameters to a function are expressions, and
there are standard unary conversions (also standard binary conversions) that
are applied to arithmetic types appearing in expressions.  The usual unary
conversions (defined in K&R) include widening char and short to int and float
to double.   These are applied to parameters in function calls and do not
depend on any declarations of the types of parameters.

--------
Kenneth R. Ballou			ARPA:  ballou@brahms
Department of Mathematics		UUCP:  ...!ucbvax!brahms!ballou
University of California
Berkeley, California  94720
--------
Kenneth R. Ballou			ARPA:  ballou@brahms
Department of Mathematics		UUCP:  ...!ucbvax!brahms!ballou
University of California
Berkeley, California  94720

adam@mtund.UUCP (Adam V. Reed) (12/17/86)

> Keywords:
> 
> My program:
> >> unsigned char ucf() { return 0xaa; }
> >> 
> >> main() {
> >> 	char c;
> >> 	unsigned char uc = 0xaa;
> >> 
> >> 	c = uc;
> >> 	printf("\tc = %x, (char)uc = %x, (char)ucf() = %x\n",
> >> 	  c, (char)uc, (char)ucf());
> >> }
> 
> Adam Reed (mtund!adam) writes:
> >Ugh. %x expects an int, so the result of feeding it a char is,
> >*and ought to be*, UNDEFINED.
> 
> Golly!  Guess they've changed the language on me again.  Last I heard,
> char variables were converted to int whan passed as parameters.  That meant
> that when I did something like this I could see what the compiler produced
> when it converted the expression to int.  Guess I'll have to go back to writing
> 	int i, j, k;
> 	...
> 	i = c;
> 	j = (char)uc;
> 	k = (char)ucf();
> and looking at the result with adb.  It's SO hard to keep up with these things!
> 
> In case anyone wonders, the point of this question was that the 4.3 VAX C
> compiler sometimes throws away casts when it's doing promotions.  I don't
> believe this is correct, and those who have addressed that issue (by mail as
> well as by posting) have agreed.  Thanks to all of you who wrote.

Alternatively, and as I assumed, casting an argument may be interpreted by
your compiler as a directive to promote it to the type specified by the
cast, instead of the default (K&R p.24) int. Given the obvious utility of
such a feature, I still suspect that this is what it does. Could you check?
					Adam Reed (mtund!adam)