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?