[TUHS] C++ / Kernel

ron at ronnatalie.com ron at ronnatalie.com
Fri Aug 24 08:17:06 AEST 2018



> I haven't done much BSD kernel programming in last 15 years but this is
not my recollection. BSD used caddr_t, typedefed to char*, sort of as void
*. IIRC void* 
>came in common use after BSD unix first came about. Why use a union when a
cast will do? :-) The union trick is more likely to be used for esoteric
things 
> (like getting at fl.pt. bytes) or for more complex types or probably by
people with lots of programming experience in pascal and not so much in C
(in Pascal 
>you *had* to use untagged variant records if you wanted to cheat!). In C,
all that void* does is allow you to avoid casts in some cases.

Your recollections are certainly wrong.    I spent a lot of time tracing
down why the Kernel crashed doing I/O and traced it to this and spent a
while undoing it as I stated.
This union was right in the middle of the buf struct:

	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 */
	    daddr_t *b_daddr;		/* indirect block */
	} b_un;
There were a number of other places that did the same thing.   It's
OFFICIALLY now in undefined behavior by the standard (though of course that
didn't exist in the BSD days) ,
to store in one element of the union and retrieve it via another.   This is
one of the reasons why.

This isn't the only place it occurs.

Void* came out with the V7 compiler, if I recall properly.   The BSD kernel
looks as if it requires such a later compiler (it uses bit fields which the
earlier compilers didn't support).
But it doesn't matter.   You are right char* (or caddr_t) would work just
fine for this albeit with some explicit casting.





More information about the TUHS mailing list