__packed

__packed 修飾子を指定すると、すべての有効型の境界整列が 1 に設定されます。したがって、以下のようになります。

構造体または共用体が __packed 修飾子を使用して宣言されている場合、そのすべてのメンバに __packed 修飾子が適用されます。メンバ間にも構造体の終わりにもパディングは挿入されません。パック構造体のすべてのサブ構造体は、__packed を使用して宣言する必要があります。非パック構造体の整数サブフィールドは個々にパックできます。

Show/hide使用法

__packed 修飾子は、構造体を外部のデータ構造体にマップしたり、非境界整列データにアクセスしたりする際に使用すると効果的ですが、非境界整列アクセスにかかるコストが比較的高いため、一般的には、データサイズの削減には効果がありません。非境界整列アクセスの数は、パックする必要のある構造体にフィールドをパックすることによってのみ減らすことができます。

Note

ハードウェアで非境界整列アクセスをサポートしていない ARM プロセッサ(ARMv6 以前のプロセッサなど)では、コードサイズおよび実行速度において、非境界整列データへのアクセスにコストがかかる場合があります。コードサイズの増大とパフォーマンスの低下を避けるため、パック構造体を介したデータアクセスは最小限に抑える必要があります。

Show/hide制約条件

__packed を使用する場合は、以下の制限が適用されます。

  • __packed 修飾子は、前に __packed を使用せずに宣言された構造体には使用できません。

  • 他の型修飾子とは異なり、構造体の型については、同じ型について __packed バージョンと __packed 以外のバージョンの両方を使用することはできません。

  • __packed 修飾子は、整数型のローカル変数には影響しません。

  • パック構造体または共用体は、対応する非パック構造体との代入互換性はありません。構造体によって使用されるメモリレイアウトは異なるため、パック構造体を非パック構造体に割り当てるには、フィールドごとにコピーする以外に方法はありません。

  • char 型を除き、__packed を使用しない場合のキャストの影響については定義されていません。非パック構造体をパック構造体にキャストした場合、またはパック構造体をパック構造体にキャストした場合の影響についても定義されていません。非パック整数型へのポインタは、明示的、暗示的を問わず、パック整数型へのポインタに適切にキャストできます。

  • パック配列型はありません。パック配列とは、パック型のオブジェクトの配列を指します。配列はパディングされません。

Show/hide

Example 8の場合は、ポインタを使用して、パック型を指すことができます。

Example 8. パックへのポインタ

typedef __packed int* PpI;          /* __packed int へのポインタ */
__packed int *p;                    /* __packed int へのポインタ */
PpI p2;                             /* 'p2' は 'p' と同じ型 */
                                    /* __packed は修飾子  */
                                    /* 'const' や 'volatile' と同様 */
typedef int *PI;                    /* int へのポインタ */
__packed PI p3;                     /* 通常の int への __packed ポインタ */
                                    /*  -- 'p' や 'p2' と同じ型ではない */
int *__packed p4;                   /* 'p4' は 'p3' と同じ型 */

Example 9 では、ポインタを使用してパックオブジェクトにアクセスする場合、コンパイラによって、ポインタの境界整列に依存せずに機能するコードが生成されるのを示します。

Example 9. パック構造体

typedef __packed struct
{
    char x;                   // すべてのフィールドは __packed 修飾子を継承	
    int y;
} X;                          // 5 バイト構造体(自然境界整列は 1)	
int f(X *p)
{
    return p->y;              // 非境界整列読み出し
}
typedef struct
{
    short x;
    char y;
    __packed int z;           // このフィールドのみをパックする
    char a;
} Y;                          // 8 バイト構造体(自然境界整列は 2)
int g(Y *p)
{
    return p->z + p->x;       // z についてのみ非境界整列読み出し
}

Show/hide関連項目

Copyright © 2010 ARM. All rights reserved.ARM DUI 0491BJ
Non-ConfidentialID011811