2017-07-21 19 views
4

埋め込みの仕組みを理解しています。私は整列が何であるか知っています。私にとって奇妙なのは、なぜcharフィールドのみの構造体のサイズが4バイト(最後にパディング)に揃えられていないのですか?私はこれが仕様によって保証されていないと考えているので、コンパイラはそれをしません。そのような場合は、そのような規則への言及を得ることができますか?私は主にx86とx86-64のアーキテクチャーに興味があります。sizeof c構造体のcharフィールドのみ

例:

struct foo { 
    char field1; 
    char field2; 
    char field3; 
} foo2; 

int main(void) 
{ 
    printf("sizeof=%lu\n", sizeof foo2); 
} 

出力:sizeof=3

+1

パディングはどこですか?あなたは3つの 'char'sを持っているので、3バイトあります。 – drum

+4

ほとんどのシステムでバイト( 'char'はほとんどのプラットフォームでは8ビットのバイト)が奇数アドレスと偶数アドレスの両方でアクセスできるので、構造体は最後に埋められる必要はありません。 。 –

+1

ARM OABI(apcs-gnu)では、これは4バイト境界になります。 (なぜ私に聞かないで、そのABIは多くの意味をなしません) –

答えて

6

構造の配向は(それらがアレイの一部ている場合は特に)そのすべてのフィールドも正しく整列されるようなものでなければなりません。

ここではすべてのフィールドの配置要件が1であるため、構造自体の配置要件でもあります。

つまり、これらの構造の2つを隣り合わせに配置すると、どちらの構造のフィールドもアラインメント要件に違反しません。

struct moreComplexCase { 
    char char1WithAlignment1; 
    // 3 byte gap to align below item. 
    unint32_t uintWithAlignment4; 
    char char2WithAlignment1; 
    // 3 byte gap to align structure itself. 
} 

あなたはそこに2つのパディングセクションが表示されます:とすることを

コントラスト。最初は、uint32_tが正しく整列されていることを確認することです(構造体の整列も同じでなければならず、uint32_tが指定されたパディングと正しく整列するようにする必要があります)。

最終的なパディングは、配列の2番目の要素(およびそれ以降のすべての要素)も正しく整列させるためのものです。

Cの標準自体は、アライメントが何であるかを指示しません。アライメントが存在する可能性があります。例えば、早いx86チップ(そしておそらく現在のもの)は、整列していないデータをうまく処理します(または少し遅くするかもしれません)一方、他のアーキテクチャー(早いARMチップなど)は、単にクラッシュさせるか、 。

+0

さて、私はそれを持っていると思う。問題は、メモリアドレスのネイティブサイズ(x86-64では4バイト、x86-64では8バイト)で割り切れるアドレスでこの構造体にアクセスする方が良いと考えていました。しかし、これがARMやPowerPCのような他のアーキテクチャでも当てはまるかどうかは分かりますか?それは完全に移植可能ですか? – hencew5

+0

非常に多くのCPUが任意のアドレスからの個々のバイトのロードをサポートしています。主に起こっているのは、キャッシュライン全体がいっぱいになっているため、バイトをレジスタに入れるのは比較的簡単です。 Primeのメインフレーム(古代の歴史)のようなものではないマシンでは、面白いことが起こります。彼らはレジスタにロードできるデータの最小単位だった16ビットワードを持っていました。 – bazza

+0

"あなたがそれをやろうとすると、他のアーキテクチャは安価なスーツのように折り畳まれます。"アライメントの合っていないアクセスでこのようなアーキテクチャに多大な負荷やオーバーヘッドは必要ないということですか?私はネイティブスピーカーではないので、このコンテキストで「折り畳み」が意味することはかなり混乱しています:) – hencew5

関連する問題