chris@mimsy.UUCP (Chris Torek) (07/04/87)
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: >>On a machine where "char" is not signed, this won't work.... "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? No. (Sorry.) >Now of course K&R say that an expression is coerced to the type >it is being assigned to. As does the draft C standard. This is pretty well set in concrete. >... Or phrased a little differently, is the comparison being made >to the value of c or the value of the getchar() ? According to the C language definitions, the comparison is being made to the value of c. >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() )'. It does and should. >Interestingly enough, the VAX 4.2bsd cc agrees with me, It is buggy. (This is a surprise? :-) ) >and produces (code to get value of getchar() ommited, but it's in r0): > > 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 This is an incorrect optimisation. The `officially proper' code is cvtlb r0,-1(fp) cvtbl -1(fp),r0 cmpl r0,$-1 jeql L36 which can be simplified to cvtlb r0,-1(fp) cvtbl r0,r0 cmpl r0,$-1 jeql L36 or (4.3BSD cc uses this) cvtbl r0,-1(fp) cmpb r0,$-1 # legal iff `char' is signed jeql L36 Note, however, that the values returned by `getchar' are all in the range -1..255. Since `cvtbl' sign extends a byte, the only case this misses is 255, which should compare equal, but does not. The combination of proper source code (the coder *meant* to compare the `char' c with the value -1) with improper object code yeilding improper results is so rare that no one noticed it for years. >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 ); It is 5.0; 4.3BSD PCC gets it right. >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. For better or for worse, C is defined in a way that you have found astonishing. If you wish to define a new language that works the other way, that is fine, but please do not call it `C'. (While you are defining, you might fix some of the things *I* think are warts. But I will not call it `C' either.) (Incidentally, given the definition of a C cast, your final example would be equivalent to your penultimate, were the value of an assignment the value of the right hand side. You would still get 5.5. You could redefine casting, of course.) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) Domain: chris@mimsy.umd.edu Path: seismo!mimsy!chris
peter@sugar.UUCP (Peter DaSilva) (07/06/87)
Make c an int. No problem. EOF is not a valid character, and you get the benefit that you can add other out-of-band information. if((c = getch(ttyfd)) != EOF) { switch(c) { case FRAMING_ERROR: case BREAK: case PARITY_ERROR: } } -- -- Peter da Silva `-_-' ...!seismo!soma!uhnix1!sugar!peter (I said, NO PHOTOS!)