4.1.11. __packed

__packed 限定符将任何有效类型的对齐边界设置为 1。 这意味着:

使用 __packed 限定符声明结构或联合后,__packed 将应用于该结构或联合的所有成员。 成员之间或结构末尾均没有填充。 必须使用 __packed 声明压缩结构的所有子结构。 可以单独压缩非压缩结构的整型子字段。

用法

在将结构映射到外部数据结构或访问未对齐的数据方面,__packed 限定符非常有用;但由于访问开销相对较高,通常对节省数据大小并没有什么帮助。 通过仅对需要压缩的结构中的字段进行压缩,可以减少未对齐访问的数量。

Note

在硬件中不支持未对齐访问的 ARM 处理器(例如,ARMv6 之前的处理器)上,访问未对齐的数据时可能会在代码大小和执行速度方面产生较高的成本。 必须最大限度减少通过压缩结构进行的数据访问,以避免增加代码大小和降低性能。

限制

以下限制适用于使用 __packed 的场合:

  • __packed 限定符不能用于以前未使用 __packed 声明的结构。

  • 与其他类型限定符不同,不能同时具有同一结构类型的 __packed 版本和非 __packed 版本。

  • __packed 限定符不影响整型局部变量。

  • 压缩结构或联合与相应的非压缩结构的分配不兼容。 由于这些结构具有不同的内存布局,因此,将压缩结构分配给非压缩结构的唯一办法是逐个字段进行复制。

  • 没有定义对 __packed 进行类型转换所产生的影响。 也没有定义将非压缩结构类型转换为压缩结构类型所产生的影响。 可以合法地将指向整型的指针类型显式或隐式转换为指向压缩整型的指针类型。 也可以对 char 类型进行 __packed 类型转换。

  • 不存在压缩数组类型。 压缩数组是指具有压缩类型的对象数组。 数组中没有进行填充。

示例

Example 4.4 说明了指针可以指向压缩类型。

Example 4.4. 指向压缩类型的指针


typedef __packed int* PpI;          /* pointer to a __packed int */

__packed int *p;                    /* pointer to a __packed int */

PpI p2;                             /* 'p2' has the same type as 'p' */

                                    /* __packed is a qualifier  */

                                    /* just like 'const' or 'volatile' */



typedef int *PI;                    /* pointer to int */

__packed PI p3;                     /* a __packed pointer to a normal int */

                                    /*  -- not the same type as 'p' and 'p2' */



int *__packed p4;                   /* 'p4' has the same type as 'p3' */

Example 4.5 说明了使用指针访问压缩对象时,编译器可生成有效代码,并且代码与指针对齐方式无关。

Example 4.5. 压缩结构


typedef __packed struct

{

    char x;                   // all fields inherit the __packed qualifier	

    int y;

} X;                          // 5 byte structure, natural alignment = 1	



int f(X *p)

{

    return p->y;              // does an unaligned read

}



typedef struct

{

    short x;

    char y;

    __packed int z;           // only pack this field

    char a;

} Y;                          // 8 byte structure, natural alignment = 2



int g(Y *p)

{

    return p->z + p->x;       // only unaligned read for z

}

另请参阅

Copyright © 2007 ARM Limited. All rights reserved. ARM DUI 0348AC
Non-Confidential