変数の順序だけではありません。あなたは決して使用s1
せず、コンパイラは単純にそれを最適化し、スタックにスペースを割り当てません。
a
あなたのようにとのアドレスだけを印刷しようとするとb
、次のようになります。
ffeb7448 (&a)
ffeb7444 (&b)
つまり、4 バイトの違いです。
のアドレスも出力しようとすると、次のようになりますs1
(したがって、宣言を使用s1
することになります)。
ffe109cc (&a)
ffe109c8 (&s1)
ffe109c4 (&b)
a
実際にはとb
今回の間にあることがわかります(他の回答がすでに指摘しているように、必ずしもそうである必要はありません)。a
とb
は 4 ではなく 8 バイトで区切られています。
わずかに関連するもう 1 つのポイントは、配置に関係しています。
例えば:
struct foo
{
int a;
char b;
};
この構造体は、4 バイト整数のマシンでは 5 バイト幅のように見えますが、私のコンパイラはsizeof (struct foo) == 8
.
これは、foo
が常に 8 バイト境界で整列されるようにするためです (これには、struct foo
ローカル変数の使用が含まれます)。
例えば
int bar (void)
{
struct foo a;
struct foo b;
/* Do some work. */
}
ここでは、a
とは、実際にはそれぞれ 5 バイトしか使用しb
ていませんが、私のマシンのコンパイラでは 8 バイトで区切られています。foo
これでわかることは、コードを書くときに、幅、配置、相対位置などに関連するものを決して想定しないことです。