On Thu, Aug 23, 2018 at 6:29 PM Nevin Liber wrote: > It was still kinda frowned upon in K&R1: "It is the responsibility of the > programmer to keep track of what type is currently stored in a union; the > results are machine dependent if something is stored as one type and > extracted as another." > No. It was not frowned upon, it was widely used. The message was just just Dennis and Brian giving you fair warning. Remember K&R1 came out approx the same time as 7th edition [I saw the proofs for the book with UNIX/TS which was a little earlier, but pretty much the same kernel]. From V7th editions buf.h (which I show a date of May 5, 1979) and Ron is correct void*, caddr_t, daddr_t, dev_t and the like; were all 7th edition-isms that BSD picked up) ... struct buf { int b_flags; /* see defines below */ struct buf *b_forw; /* headed by d_tab of conf.c */ struct buf *b_back; /* " */ struct buf *av_forw; /* position on free list, */ struct buf *av_back; /* if not BUSY*/ dev_t b_dev; /* major+minor device name */ unsigned b_bcount; /* transfer count */ union { caddr_t b_addr; /* low order core address */ int *b_words; /* words for clearing */ struct filsys *b_filsys; /* superblocks */ struct dinode *b_dino; /* ilist */ls -l buf.h daddr_t *b_daddr; /* indirect block */ } b_un; daddr_t b_blkno; /* block # on device */ char b_xmem; /* high order core address */ char b_error; /* returned after I/O */ unsigned int b_resid; /* words not transferred after error */ }; ...