Ensuring field alignment in struct

Viewed 66

I'm designing an abstract syntax tree (AST) for a language. My lexical tokens look like

typedef struct {
    tokenHeader header;
    tokenData data;
} lexicalToken;

where tokenHeader and tokenData are structs. As for my AST nodes, I have a base type:

#define AST_HEADER \
    struct astNode *parent; \
    tokenHeader header;

typedef struct astNode {
    AST_HEADER
} astNode;

along with some splitting types. E.g.,

typedef struct {
    AST_HEADER
    astNode *nodes[2];
} astTwoSplitNode;

The reason why I don't include tokenData in AST_HEADER is because almost all tokens don't use that field. This brings me to

typedef struct {
    astNode *parent;
    lexicalToken token;
    // Nodes which use tokenData are always terminal nodes.
} astNodeWithData;

This finally brings me to my question: Is astNodeWithData guaranteed to be arranged in such a way that I can cast an astNodeWithData* to an astNode*, reference the header field, and access its fields in the expected way?

If not, is there a way to instruct my compiler (gcc, if it helps) to enforce such an arrangement?

1 Answers

What you can actually do is cast a astNodeWithData * to a astNode **, not a astNode *, as the address of a struct is the same as the address of the first member.

Section 6.7.2.1p15 of the C standard regarding "Structure and union specifiers" states:

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning

So the following would be allowed:

astNodeWithData dataNode;
// populate dataNode
astNode **nodePtr = (astNode **)&dataNode;
// access (*nodePtr)->header
astNodeWithData *dataNodePtr = (astNodeWithData *)nodePtr;
// access dataNodePtr->token
Related