プログラミング C言語 復習 構造体 共用体 offsetof

offsetofマクロの存在を知る。

#include <stdio.h>
#include <stddef.h>
typedef enum {
        OP_CHAR,
        OP_CONCAT,
        OP_ALTER,
        OP_CLOSURE,
        OP_NULL
 } Op_t;

typedef struct Tree {
        Op_t Op;
        union {
        char c;
                struct {
                        struct Tree *_left;
                        struct Tree *_right;
                  }X;
          }U;
}Tree_t;

int main(void)
{
        Tree_t t;
        printf("t=%d,op=%d,o_op=%d,U=%d,o_U=%d,X=%d,c=%d,%p\n",sizeof(Tree_t),sizeof(t.Op),
                        offsetof(Tree_t,Op),sizeof(t.U),offsetof(Tree_t,U),sizeof(t.U.X),sizeof(t.U.c),&t);
        printf("%p,%p\n",&t.U.c,&t.U.X);
        return 0;
}

./a.out
t=12,op=4,o_op=0,U=8,o_U=4,X=8,c=1,7f7f1178
7f7f117c,7f7f117c

Tree_t型の構造体tはメンバに列挙型OP_tのOpと、
無名共用体のUを持つ。
無名共用体Uはメンバにchar型のcと、無名構造体Xを持つ。
無名構造体XはメンバにTree_t型へのポインタ*_leftと*_rightを持つ。
構造体tはぱっと見Op=4+c=1+*_left=4+*_right=4=13バイトのサイズを持ちそうだが、
cと無名構造体Xはアドレスを共有しているので、
Op=4+*_left=4+*_right=4=12バイトのサイズを持つ。