__attribute__系列之aligned
__attribute__的属性aligned,作用是为了设置字节对齐。
aligned是对 变量和结构体进行 字节对齐的属性设置。
通过aligned属性设置(aligned(对齐字节数)),可以显示的设置对齐字节数,如果使用缺省属性(aligned()),编译器会有一个默认的字节对齐数。
aligned特性:aligned属性只能增加对齐字节数,不能减少到比默认对齐字节数还小。
aligned支持的最大对齐字节数由linker决定。
aligned (
alignment)
This attribute specifies a minimum alignment for the variable or structure field, measured in bytes. For example, the declaration:
int x __attribute__ ((aligned (16))) = 0;
causes the compiler to allocate the global variable x
on a 16-byte boundary.
设置指定大小的对齐格式
You can also specify the alignment of structure fields. For example, to create a double-word aligned int
pair, you could write:
struct foo { int x[2] __attribute__ ((aligned (8))); };
This is an alternative to creating a union with a double
member that forces the union to be double-word aligned.
As in the preceding examples, you can explicitly specify the alignment (in bytes) that you wish the compiler to use for a given variable or structure field. Alternatively, you can leave out the alignment factor and just ask the compiler to align a variable or field to the maximum useful alignment for the target machine you are compiling for. For example, you could write:
short array[3] __attribute__ ((aligned));
Whenever you leave out the alignment factor in an aligned
attribute specification, the compiler automatically sets the alignment for the declared variable or field to the largest alignment which is ever used for any data type on the target machine you are compiling for. Doing this can often make copy operations more efficient, because the compiler can use whatever instructions copy the biggest chunks of memory when performing copies to or from the variables or fields that you have aligned this way.
The aligned
attribute can only increase the alignment; but you can decrease it by specifying packed
as well. See below.
Note that the effectiveness of aligned
attributes may be limited by inherent limitations in your linker. On many systems, the linker is only able to arrange for variables to be aligned up to a certain maximum alignment. (For some linkers, the maximum supported alignment may be very very small.) If your linker is only able to align variables up to a maximum of 8 byte alignment, then specifying aligned(16)
in an __attribute__
will still only provide you with 8 byte alignment. See your linker documentation for further information.
对变量设置aligned属性:
1 int i __attribute__ ((aligned (16))) = 0 ; 2 printf("address of i:%p\n",&i); 3 int j __attribute__ ((aligned (8))) = 0 ; 4 printf("address of j:%p\n",&j); 5 int k __attribute__ ((aligned (4))) = 0 ; 6 printf("address of k:%p\n",&k); 7 int m __attribute__ ((aligned (1))) = 0 ; 8 printf("address of m:%p\n",&m);
运行结果如下:
address of i:0xbfa43920
address of j:0xbfa43918
address of k:0xbfa43914
address of m:0xbfa43910
对于标准数据类型,它的地址只要是它的长度的整数倍就行了,而非标准数据类型按下面的原则对齐:
数组 :按照基本数据类型对齐,第一个对齐了后面的自然也就对齐了。
联合 :按其包含的长度最大的数据类型对齐。
结构体: 结构体中每个数据类型都要对齐。
对于设置结构体成员的属性:
1 #include <stdio.h> 2 3 struct p 4 { 5 int a; 6 char b; 7 char c; 8 }__attribute__((aligned(4))) p1; 9 10 11 12 int main(int argc, char** argv) 13 { 14 printf("sizeof(int):%d, sizeof(char)=%d\n", sizeof(int), sizeof(char)); 15 printf("sizeof(p1):%d\n", sizeof(p1)); 16 17 return 0; 18 }
int a占用4字节,char a占用字节,char c占用1字节。那么,
sizeof(int):4, sizeof(char)=1
sizeof(p1):8
1 #include <stdio.h> 2 3 struct p 4 { 5 int a; 6 char b; 7 char c; 8 }__attribute__((aligned(4))) p1; 9 10 11 struct q 12 { 13 int a; 14 char b; 15 struct p qn; 16 char c; 17 }__attribute__((aligned(8))) q2; 18 19 20 int main(int argc, char** argv) 21 { 22 printf("sizeof(int):%d, sizeof(char)=%d\n", sizeof(int), sizeof(char)); 23 printf("sizeof(q2.a)=%d, sizeof(q2.b)=%d,sizeof(q2.qn)=%d, sizeof(c)=%d",sizeof(q2.a), sizeof(q2.b),sizeof(q2.qn), sizeof(q2.c)); 24 printf("sizeof(q2):%d\n", sizeof(q2)); 25 26 return 0; 27 }
sizeof(int):4, sizeof(char)=1
sizeof(q2.a)=4, sizeof(q2.b)=1,sizeof(q2.qn)=8, sizeof(c)=1sizeof(q2):24