总结:
- aligned规定了最小的对齐边界,即变量首地址需要为对齐边界的整数倍;
- aligned只能增大结构体及其成员的对齐边界,若想降低,需同时指定packed;
- typedef不受第2条影响。即可增大也可减小对齐边界;
- 对齐不影响变量的空间占用(sizeof);但对于结构体,由于其要保证数组的对齐,会产生尾随填充,因此不同的对齐,结构体的空间占用可能发生变化。
gcc对aligned属性的解释。
Common Variable Attributes (Using the GNU Compiler Collection (GCC))
以下是aligned部分的原文翻译
aligned
aligned (对齐字节数)
aligned
属性指定了变量或结构体的最小对齐字节数。该字节数必须是2的次幂。未指定字节时,对目标采用最大的对齐字节,经常为8或16字节(并不总是)。例如,对于以下声明:
int x __attribute__ ((aligned (16))) = 0;
编译器会将全局变量
x
分配在16字节边界上。在68040上,可以与asm
表达式结合使用,以满足move16
这一指令16字节对齐操作数的要求。同样可以对结构体指定对齐字节数。例如,可以这么创建一个按照
double
对齐的int
对:struct foo { int x[2] __attribute__ ((aligned (8))); };
另一可选方式是通过包含
double
类型成员的联合体完成,这将强制使联合体按照double
对齐。正如上述示例,可以显式指定期望编译器用于给定变量或结构体的对齐字节数。另外,也可以缺省对齐字节数,那么编译器将按照目标架构的默认对齐字节数对变量和结构体进行对齐。默认的对齐字节数对标量类型是充分的,但对支持矢量操作的目标上的所有矢量类型可能并不足够。对于确定的目标ABI,默认对齐字节数是固定的。
GCC提供了目标定义的宏
__BIGGEST_ALIGNMENT__
,这是所编译的目标平台上对任意数据类型所使用的最大对齐字节数。例如,下述写法:short array[3] __attribute__ ((aligned (__BIGGEST_ALIGNMENT__)));
编译器将自动设置所声明的变量或结构体的对齐字节数为
__BIGGEST_ALIGNMENT__
。如此做可以使拷贝操作的效率得到提升,因为在拷贝自或拷贝到按照该方式对齐的变量或结构体时,编译器可以采用任何指令来拷贝最大的内存块。注意,__BIGGEST_ALIGNMENT__
的值可能会因命令行选项而改变。当用在结构体或结构体成员上时,
aligned
属性仅能增加对齐字节数。若想降低对齐字节数,必须同时指定packed
属性。当用作typedef的一部分时,aligned
属性既可增大也可减小对齐字节数,且若指定packed
属性将产生警告。注意,
aligned
属性对静态变量的效果可能受限于系统链接器和/或对象文件格式中固有限制。在某些系统上,链接器对变量的对齐字节数只能达到某个确定的值。(对于某些链接器,支持的最大对齐字节数可能非常非常的小。)如果链接器最大仅能按照8字节对齐变量,那么在__attribute__
中指定aligned(16)
也仍只能提供8字节对齐。查阅所使用链接器的文档来获取更多信息。栈变量不受链接器约束的影响; 在任何目标上,GCC都可以很好地对其进行对齐。
aligned
属性也可以用于函数。(查阅Common Function Attributes.)
关于结构体大小和对齐的关系的一点补充:
sizeof 运算符 - cppreference.com
应用 sizeof 到结构体或联合体类型运算数时,结果是这种对象中的总字节数,包含内部和尾随填充。尾随填充使得若对象在数组中,则此数组中下个元素的对齐要求会得到满足。