Linux __attribute__((aligned(n)))和#pragma pack

字节对齐

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…

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值