Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rochester!pt!cadre!pitt!amanue!jr From: jr@amanue.UUCP (Jim Rosenberg) Newsgroups: comp.lang.c Subject: Re: Writing readable code Message-ID: <225@amanue.UUCP> Date: Sun, 5-Jul-87 02:11:47 EDT Article-I.D.: amanue.225 Posted: Sun Jul 5 02:11:47 1987 Date-Received: Sun, 5-Jul-87 20:52:14 EDT References: <1158@copper.TEK.COM> <6858@auspyr.UUCP> <17171@cca.CCA.COM> <262@auvax.UUCP> Organization: Amanuensis Inc., Grindstone, PA Lines: 75 Summary: **NEVER** put getchar()'s result into a char!! In article <262@auvax.UUCP>, rwa@auvax.UUCP (Ross Alexander) writes: > The following discussion is all relative to > > #define EOF -1 > char c; > while ( ( c = getchar() ) != EOF ) { /* do something */ } > > In article <22635@sun.uucp>, guy%gorodish@Sun.COM (Guy Harris) writes: > > > The assignment into a character causes getchar's int return > > > to be changed to char, invalidating the following comparison> > > On a machine where "char" is not signed, this won't work even if you > > run it on text consisting entirely of 7-bit characters. "getchar" > > will return EOF when it hits end-of-file; EOF (-1) will get converted > > to '\377' ... which compares equal to 255 but not to -1. > >Isn't there a little room here for arguement? Now of course K&R say >that an expression is coerced to the type it is being assigned to. >This is _a good thing_, since otherwise there's no way to assign to a >char (think about the promotion rules :-). But isn't assignment, in >the strictest sense, a side effect? Or phrased a little differently, >is the comparison being made to the value of c or the value of the >getchar() ? So the coercion for the assignment of `int' to `char' in >this case is a side effect and shouldn't have an affect on the value >of the whole expression `( c = getchar() )'. Interestingly enough, >the VAX 4.2bsd cc agrees with me ... Gads!!! On this one, when Guy talks you better listen. I earned some cute money once over exactly this point. Someone was trying to port a program from BSD on a VAX to System V on a 3B2. It ran fine on the VAX (don't they always??) but dumped core on the 3B2. In the code above c should be declared int -- nothing else, int! I can't testify to how this works on all compilers under the sun, but on the 3B2 the compiler treated char as unsigned. It considered the type of (c = getchar()) to be the type of c -- i.e. unsigned char. Since EOF was defined as -1, c received 0xff. But when the value of the assignment was compared to EOF it was coerced back to an int. Since the compiler considered it unsigned, when the value of the assignment was coerced back to an int it became plain old 0xff -- **NO SIGN EXTENSION**. When getchar() finally hit end of file the code compared 0xff to 0xffffffff and got **FALSE**. Sorry to repeat exactly what Guy just said, but it didn't seem to get through. K&R (referring to assignment operators): "The value is the value stored in the left operand after the assignment has taken place." ^^^^^ and "If both operands have arithmetic type, the right operand is converted to the type of the left preparatory to the assignment." ^^^^^^^^^^^ I don't think that leaves any room for doubt. The type of an assignment is supposed to be the type to which the rvalue must be coerced to be stored in the lvalue. H&S state explicitly: "the type of the result is equal to the (unconverted) type of the left operand." ^^^^ I don't have a copy of the ANSI draft, but I would assume they must make this explicit. K&R, in discussing whether sign extension must occur when a char is converted to an int: "Whether or not sign-extension occurs for characters is machine dependent." So there's nothing inherently broken about the way the 3B2 does it. But that code above is very definitely broken. On a 3B2 it will run right past the EOF. It works on a VAX because C on the VAX sign-extends char in promoting it to int. The VAX is probably the *WORST* machine in the world on which to try to decide if something is "clean C" by trying it and seeing if it works. All kinds of dirt work on a VAX. :-) -- Jim Rosenberg CIS: 71515,124 decvax!idis! \ WELL: jer allegra! ---- pitt!amanue!jr BIX: jrosenberg seismo!cmcl2!cadre! /