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)