通常時の構造体のフィールド(笑)のアラインメント事情

経験則に基づくソース無し&環境に依存しまくりのメモなので絶対に参考にしないように。勝手に参考にして死なれても責任取れない。

プリミティブ型だけで構成された構造体でちょこっと調査してみたところ

  • 構造体の先頭アドレス → 不明
  • フィールドのオフセットアドレスはsizeof(type)の倍数になるように配置される
  • 構造体のサイズは、サイズが一番大きいtypeのsizeof(type)の倍数になる

となる。大体のC/C++の環境と同じぽい。

struct S1 {
    char a;
    int b;
}

struct S2 {
    int a;
    char b;
}

どちらともcharの後にパディングが入って8バイト。

struct S3 {
    long a;
    char b;
    int c;
}

struct S4 {
    long a;
    int b;
    char c;
    int d;
}

struct S5 {
    char a;
    long b;
    short c;
    short d;
    int e;
}

struct S6 {
    long a;
    short b;
    short c;
    short d;
    int e;
}

struct S7 {
    long a;
    short b;
    short c;
    short d;
    char e;
    char f;
    int g;
}

struct S8 {
    long a;
    short b;
    short c;
    char d;
    short e;
    char f;
}

S3はcharの後に3バイトのパディングが入って、intは次の4の倍数のところに配置されて16バイト。S4はdのオフセットアドレスが8の倍数になるように調整されるので24バイト。S5はaの後に7バイトのパディングが入るけど、その後は8バイトにcdeと詰め込むことができるので24バイト。S6はdの直後にeを配置できず、2バイトパディングして更にeの後に4バイトのパディングが必要なので24バイト。S7はぎっちり詰め込んで24バイト。S8はdの後に1バイトパディングが入って、fの直後に7バイトのパディングが必要なので24バイト。

こんな感じだった。System.Runtime.InteropServices.Marshal.SizeOfを使ってるので本当にこれだけしか確保されてないかは知らない。