構造体メンバのアライメント

構造体のメンバはアライメントされたりされなかったりすが、実際の所どうなのか検証用のコードを書いてみた(どう書く.orgに嘘コメント書いた懺悔というかなんというか…)。開発環境および実行環境はCeleron2.40GHz + VineLinux4.2 + gcc3.3.6。

まずは、単純にchar配列のみの構造体で実験する。

#include 

struct a
{
    char c[1];
    char d[3];
    char e[3];
};

int main(void) {
    printf("%d\n", sizeof(struct a));
    return 0;
}

実行結果としては、

$ gcc test1.c
$ ./a.out
7

予想では「4バイトアライメントされるだろうから、cの後ろに3バイト、dとeの後ろに1バイトパディングされて、合計12バイト」と思っていたが、まったくパディングされないようだ。

次にintを追加してみる。メンバとしては同じものを同じ数だけ、宣言の前後のみを変える。

#include 

struct a
{
    char c[1];
    char d[3];
    char e[3];
    int f;
};

struct b
{
    char c[1];
    int f;
    char d[3];
    char e[3];
};

int main(void) {
    printf("%d, %d\n", sizeof(struct a), sizeof(struct b));
    return 0;
}

実行結果としては、

$ gcc test2.c
$ ./a.out
12, 16

char配列がパディングされなかった前の結果からすると、予想として「構造体aはeの後ろに1バイトパディングされて合計12バイト、構造体bはcの後ろに3バイトパディングされて合計14バイト」と思ったのだが、構造体bはdもeも1バイトパディングされてるのかな?
規則はよくわからないが、「アライメントされたりされなかったりする」というのは「この処理系は全部アライメント有」とか「この処理系は全部アライメント無」ではなく、一つの処理系でも文脈によってされたりされなかったりするらしい。深いなぁ。