In my entry on learning that you can use C unions for grouping struct fields into namespaces , I mentioned that the traditional version of this was done with
#define
to create convenient short names for fields that were actually hidden deeper in a
struct
than they appeared. I didn't come up with this idea on my own; instead, I'm pretty sure that where I first saw this was in Unix APIs. More exactly, in the actual implementation of Unix APIs, as visible in C header files. Most often, I think this was done because of unions in the struct, which at the time had to be named.
A typical example that I can find is in the 4.2 BSD
arpa/tftp.h
header:
struct tftphdr {
short th_opcode; /* packet type */
union {
short tu_block; /* block # */
short tu_code; /* error code */
char tu_stuff[1]; /* request packet stuff */
} th_u;
char th_data[1]; /* data or error string */
};
#define th_block th_u.tu_block
#define th_code th_u.tu_code
#define th_stuff th_u.tu_stuff
Here various
#define
s are being used to give short names to things that are actually inside a union. Today we could do this directly with an anonymous union, but those only officially appeared in C11 after being a GNU gcc extension.
(Another example is in the 4.2 BSD
wait.h
, which despite its position in the tree here was also in
/usr/include
; see
MAKEDIRS
. Another generally more internal use is in
inode.h
.)
This approach would have serious problems with
th_block
or other
#defined
d fields if they were also used in one of your own
struct
s for some other purpose. But in the very old days of C,
struct
fields had to be globally unique across your entire program, so it was common to give them a relatively unique name and you already knew you had problems if you reused a field name from what the manpage said was a
struct
that was part of a library API.
(I haven't looked at how the early C compilers implemented
struct
fields, but I suspect that the V7 C compiler just put all
struct
field names into a global table with their type and offset. This seems a very V7 shortcut.)