Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!rutgers!sri-spam!mordor!lll-tis!ames!ptsfa!ihnp4!alberta!auvax!rwa From: rwa@auvax.UUCP (Ross Alexander) Newsgroups: comp.lang.c Subject: Re: Writing readable code Message-ID: <262@auvax.UUCP> Date: Fri, 3-Jul-87 12:34:37 EDT Article-I.D.: auvax.262 Posted: Fri Jul 3 12:34:37 1987 Date-Received: Sat, 4-Jul-87 13:57:59 EDT References: <1158@copper.TEK.COM> <6858@auspyr.UUCP> <17171@cca.CCA.COM> <22635@sun.uucp> Organization: Athabasca U., Alberta, Canada Lines: 60 Summary: isn't assignment a side effect? 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, and produces (code to get value of getchar() ommited, but it's in r0): L9998: cvtlb r0,-1(fp) ; coercion and assignment to c as byte cmpl r0,$-1 ; but comparison is int to int jeql L36 ; break the loop iff same whilst the SUN 4.2 cc feels otherwise, and produces (getchar() value in d0): L2000001: movb d0,a6@(-0x1) ; assignment to c cmpb #-0x1,d0 ; comparison of a byte to a byte jeq L23 ; break loop iff same Now while some might argue that the second interpretation is properly conformant, and the first is brain-damaged (smile, gentle people), I would argue that the first way of doing things is less likely to get the poor programmer (myself, for instance) into trouble. I argue that this is because in this context, the assignment is a side effect, and isn't intended to `narrow' the value of the expression. Just to point out where the logical extension of case two gets us, what is the value of x in this fragment: float x; int i; x = 2.0 + ( i = 3.5 ); I would say 5.5; others might say 5.0, it seems. But if I _wanted_ 5.0, I would expect to write x = 2.0 + (int) ( i = 3.5 ); and I appeal to the principle of least astonishment for justification. ...!ihnp4!alberta!auvax!rwa Ross Alexander @ Athabasca University