v7 C features/bugs vs. 4.2bsd putc

Geoff Collyer geoff at utcsstat.UUCP
Mon Sep 17 21:42:26 AEST 1984

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))


#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).

More information about the Comp.lang.c mailing list