geoff@utcsstat.UUCP (Geoff Collyer) (09/17/84)
I've been examining the definition of putc to see why it doesn't work as advertised on 4.2bsd. In particular, putc(0377) returns -1 rather than the correct 0377. This seems to be due to a conspiracy of features/bugs in the v7 cc and all known stdio's: (1) in (unsigned)*cp v7 cc treats cp as an (unsigned char *) [the infamous uucp checksum `feature'], (2) in the v7 cc, the value of (*cp++ = (unsigned)(c)) is erroneously the right-hand side rather than the left-hand side as Kernighan & Ritchie promises in section 7.14 of the reference manual (appendix A), (3) putc() uses both bugs to advantage. We noticed these bugs because we modified our v7 cat to check putc returns but on moving it to 4.2 found that lint uses cat to concatenate C compiler intermediate language and cat generates spurious Error 0 complaints upon seeing 0377 bytes. The 4.2 cc doesn't have bug 2 nor probably bug 1 and their absence broke putc. Everyone should change putc in /usr/include/stdio.h from #define putc(x,p) (--(p)->_cnt>=0? ((int)(*(p)->_ptr++=(unsigned)(x))):_flsbuf((unsigned)(x),p)) to #define putc(x,p) (--(p)->_cnt>=0? ((int)(*(p)->_ptr++=(x)))&0377: _flsbuf((x)&0377,p)) Yes, this probably does cost a microsecond or two, but it makes putc more portable (the 0377 may have to be adjusted for machines with bytes other than eight bits long).
gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (09/21/84)
UNIX System V users are advised NOT to change the putc() macro definition in <stdio.h>, since it is already correct.