[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