目录
字节对齐
1. 什么是字节对齐
在C语言中,数据结构是一种复合的数据类型,其构成元素既可以是基本的数据类型(例如,int、long、char、bool等)的变量,也可以是复合数据类型(例如,数组、链表、数据结构等)的数据单元。在数据结构中,编译器为其每个成员按照正常边界进行空间分配。各个成员按照它们被声明的顺序在内存中进行存储,第一个成员的地址和整个数据结构的地址相同。
为了是CPU能够对变量进行快速的访问,变量的起始地址具有某些特性,即字节对齐。例如int,其字节长度为4字节,那么它的起始地址应该位于4字节倍数的起始地址上。
2. 字节对齐作用
1) 字节对齐有利于cpu的快速访问;
2) 合理利用字节对齐可以有效的节省存储空间。
C语言中字节对齐
1. __attribute__关键字
__attribute__: 关键字__attribute__允许在定义struct、union等类型时,指定特殊属性。此关键字后面是跟双括号来进行属性说明的。__attribute__不属于标准C语言,它是GCC对C语言的扩展用法。
__attribute__((aligned(n))): 指定了指定类型的变量的最小对齐(以字节为单位)。若数据结构中有成员的长度大于n,测按照最大成员的长度对齐。注意: 对齐属性的有效性守卫链接器(linker)限制,若链接器不支持16字节对齐,那么当配置16字节对齐的时候,它也仅仅提供链接器所支持的对齐方式。
__attribute__((packed)): 取消编译过程中的优化对齐。
2. pragma pack
使用伪指令#pragma pack(n),进行字节对齐,C编译器将按照n个字节进行对齐;
使用伪指令#pragma pack(),取消自定义字节对齐,采用自然边界条件分配空间的方式。
代码案例
#include <iostream>
using namespace std;
//#define MY_ALIGNED(n) __attribute__((aligned(n)))
#define MY_ALIGNED(n) __attribute__((aligned(n)))
#define MY_ALIGNED1 MY_ALIGNED(1)
#define MY_ALIGNED4 MY_ALIGNED(4)
#define MY_ALIGNED8 MY_ALIGNED(8)
#define MY_ALIGNED16 MY_ALIGNED(16)
#define MY_ALIGNED32 MY_ALIGNED(32)
#define MY_ALIGNED64 MY_ALIGNED(64)
//using __attribute__((aligned(8))) my_int32 = int;
typedef int my_int32 __attribute__((aligned(16)));
typedef struct {
char a;
float b;
short c;
} S;
typedef struct MY_ALIGNED1 {
char a;
float b;
short c;
} S_1;
typedef struct MY_ALIGNED4 {
char a;
float b;
short c;
} S_4;
typedef struct MY_ALIGNED8 {
char a;
float b;
//short c;
} S_8;
typedef struct MY_ALIGNED16 {
char a;
float b;
short c;
}S_16;
typedef struct MY_ALIGNED32 {
char a;
float b;
short c;
} S_32;
typedef struct MY_ALIGNED64 {
char a;
float b;
short c;
} S_64;
#pragma pack(1)
typedef struct {
char a;
float b;
short c;
} S_pack_1;
#pragma pack()
#pragma pack(2)
typedef struct {
char a;
float b;
short c;
} S_pack_2;
#pragma pack()
int main(int argc, char** argv){
cout << "S: " << sizeof(S) << endl;
cout << "S_1: " << sizeof(S_1) << endl;
cout << "S_4: " << sizeof(S_4) << endl;
cout << "S_8: " << sizeof(S_8) << endl;
cout << "S_16: " << sizeof(S_16) << endl;
cout << "S_32: " << sizeof(S_32) << endl;
cout << "S_64: " << sizeof(S_64) << endl;
cout << "S_pack_1: " << sizeof(S_pack_1) << endl;
cout << "S_pack_2: " << sizeof(S_pack_2) << endl;
// alignof,查询数据结构对齐要求
cout << "aligned: " << alignof(int) << ", my_int32: " << alignof(my_int32) << endl;
return 0;
}
// 输出结果:
S: 12
S_1: 12
S_4: 12
S_8: 8
S_16: 16
S_32: 32
S_64: 64
S_pack_1: 7
S_pack_2: 8
aligned: 4, my_int32: 16
__attribute__扩展
__attribute__机制是GNU C的一大特色,可用于设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。
1. 函数属性
函数属性参数有: aligned、alloc_size、noreturn、return_twice、(noline, noclone)、always_inline、flatten、pure、const、nothrow、sentinel、format、format_arg、no_instrument_function、(no_split_stack, section)、(constructor, destructor)、used、unused、deprecated、weak、malloc、alias、ifunc、warn_unused_result、nonnull、gnu_inline、externally_visible、hot、cold、artificial、error、warning…
2. 变量属性
变量属性参数有: aligned、cleanup、common、nocommon、deprecated、mode、packed、section、shared、tls_model、unused、used、vector_size、selectany、weak、dllimport、dllexport…
3. 类型属性
类型属性参数有: aligned
packed、transparent_union unused、deprecated、visibility、may_alias…