2016-06-25 7 views
1

Alignasは私が期待しているとおり動作していません。これは私のコードです:期待通りの結果が得られないC - アライナスC11の

#include <inttypes.h> 
#include <stdalign.h> 
#include <stdio.h> 

struct A 
{ 
    alignas(int32_t) int16_t a; 
    int16_t b; 
}; 

struct B 
{ 
    int16_t a; 
    alignas(int32_t) int16_t b; 
}; 

struct C 
{ 
    int16_t a; 
    int32_t b; 
}; 

struct D 
{ 
    int32_t a; 
    int16_t b; 
}; 

int main(void) 
{ 
    printf("%zu, %zu\n", alignof(int16_t), sizeof(int16_t)); 
    printf("%zu, %zu\n", alignof(int32_t), sizeof(int32_t)); 
    printf("%zu, %zu\n", alignof(struct A), sizeof(struct A)); 
    printf("%zu, %zu\n", alignof(struct B), sizeof(struct B)); 
    printf("%zu, %zu\n", alignof(struct C), sizeof(struct C)); 
    printf("%zu, %zu\n", alignof(struct D), sizeof(struct D)); 
} 

は出力:

2, 2 
4, 4 
4, 4 
4, 8 
4, 8 
4, 8 

私はすべてのこれらの構造体のサイズが同じであると予想しました。 struct Aはなぜstruct Bと同じサイズではないのですか? alignasの仕組みを誤解していますか?

答えて

5

たとえば、int16_tには2バイトの配置が必要で、int32_tには4バイトの配置が必要です。

struct A 
{ 
    alignas(int32_t) int16_t a; 
    int16_t b; 
}; 

本の自然のレイアウトはa 2バイト、bための2バイト、及び全体構造体の2バイトアラインメントであろう。

しかし、alignas(int32_t)では、追加の制約が導入されています。aは、4バイト境界で整列する必要があります。これにより、構造体全体が4バイトの境界に位置合わせされます。しかし、aのサイズはまだ2バイトなので、(4n + 2)バイト境界では、bをすぐにパディングなしで配置することができます。 bの2バイトの後、私たちは4n + 4、つまり4バイトの境界に再びあります。これは、bの後にパディングを行う必要がないことを意味します。構造体の別のインスタンスをすぐに開始することができます。

全4

struct B 
{ 
    int16_t a; 
    alignas(int32_t) int16_t b; 
}; 

、すべてに我々は(sizeof (struct A)は、そのメンバーのサイズの合計である、4)パディングなしで構造体を持っており、その第1の部材の位置合わせここで状況が異なります。aそれ自体は2バイトアライメントのみを強制します。しかし今やbは4バイトの境界に揃えられなければならないので、struct全体は4バイトの境界に揃えられ、2バイトのパディングはaの後に挿入されなければなりません。これまでのところ、2つのパディング、の2バイトは、(4n + 6)(すなわち、4n + 2)バイト境界上にあるaの2バイトを持っています。開始した状態に到達する必要があるため、bの後ろにもう2バイトのパディングが挿入され、4バイトの境界で終了するようにします。すべてのすべてで

、我々は、彼らが異なっている理由は

はsizeof与えるのサイズ8.

2

b要素がBであることを4バイトの境界に揃えるように指定しました。 aは2バイトしか必要としないため、この結果、abの間の2バイトのパディングと、bの後の2バイトが4バイトの倍数の構造になります。

Aの場合、aには4バイトのアラインメントしかありません(これは構造体の先頭にあります)。 bには余分なアライメント要件がないため、直後にパディングなしで、最後にパディングは必要ありません。

-1

を作り、パディングの2 + 2バイトとコンテンツの2つの+ 2バイトで終わりますその型またはインスタンスを格納するのに必要な実際のバイト単位のサイズ。

alignofは、最大の要素に必要なバイト単位の整列を提供します。

関連する問題