C/C++编程: __attribute__((aligned(n)))、__attribute__((packed))、__alignof

1060 篇文章 293 订阅

__attribute__GUN C中极具特设的一大机制,可以用来设置

函数属性(Function Attribute)
变量属性(Variable Attribute)
类型属性(Type Attribute)

这里我们主要阐述用__attribute__((aligned(n)))和__attribute__((packed))两个指令对结构体进行属性设置

__attribute__与结构体

理论

__attribute__((aligned(n)))   //采用n字节对齐
__attribute__((packed))       //采用1字节对齐

  • __attribute__((aligned(n)))中,n的有效参数为2的幂值,32位最大为2 ^ 32,64位为2 ^ 64,这个时候编译器会将让n与默认的对齐字节数进行比较,取较大值为对齐字节数与#pragma pack(n)恰好相反。
    *__attribute__((packed))则为取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,也就是采用1字节对齐。

在结构体类型中的使用方法如下:

/*定义结构体时不对类型重命名*/
struct mystruct
{
    /*成员变量定义*/
}__attribute__() /*(可同时在这定义变量)*/;

struct __attribute__() mystruct
{
    /*成员变量定义*/
}/*(可同时在这定义变量)*/;

/*定义结构体同时对类型进行重命名*/
typedef struct mystruct
{
    /*成员变量定义*/
}__attribute__() MS;

typedef struct __attribute__() mystruct
{
    /*成员变量定义*/
}MS;

注意:

在64位操作系统64位编译器的环境下,当n ≥ 8时,内存对齐的字节数是n,不然为8
在32位操作系统32位编译器的环境下,当n ≥ 4时,内存对齐的字节数是n,不然为4

实践

#include <stdio.h>

typedef struct mystruct1
{            //in64_64     in32_32
    int a;   //(4 + 4)        4
    double b;// 8             8
    char c;  //(1 + 15)     (1 + 3)
}__attribute__((aligned(16))) AMS1;//in 64_64:32; in 32_32:16


typedef struct __attribute__((aligned(16))) mystruct2
{            //in64_64     in32_32
    int a;   //(4 + 4)        4
    double b;// 8             8
    char c;  //(1 + 15)     (1 + 3)
}AMS2;      //in 64_64:32; in 32_32:16

struct mystruct3
{
    int a;   // 4 + 4
    double b; //8
    char c;   // 1+15
}__attribute__((aligned(16))) test3;

struct __attribute__((aligned(16))) mystruct4
{
    int a;     // 4 + 4
    double b;  // 8
    char c;    // 1 + 16
}test4;

typedef struct mystruct5
{
    int a;   //4
    double b;//8
    char c;  //1
}__attribute__((packed)) PMS5;//in 64_64:13; in 32_32:13

typedef struct mystruct6
{            //in64_64     in32_32
    int a;   //(4 + 4)        4
    double b;// 8             8
    char c;  //(1 + 7)     (1 + 3)
}__attribute__((aligned(8))) A8MS6;//in 64_64:24; in 32_32:16

typedef struct mystruct7
{            //in64_64     in32_32
    int a;   //(4 + 4)        4
    double b;// 8             8
    char c;  //(1 + 7)     (1 + 3)
}__attribute__((aligned(2))) A2MS7;//in 64_64:24; in 32_32:16

typedef struct mystruct8
{            //in64_64      in32_32
    int a;   //(4 + 4)        4
    double b;// 8             8
    char c;  //(1 + 15)     (1 + 19)
}__attribute__((aligned(32))) A32MS8;//in 64_64:32; in 32_32:32


int main(void)
{
    AMS1 test1;
    AMS2 test2;
    printf("sizeof(test1)    = %d\n", (int)sizeof(test1));
    printf("sizeof(test2)    = %d\n", (int)sizeof(test2));
    printf("sizeof(test3)    = %d\n", (int)sizeof(test3));
    printf("sizeof(test4)    = %d\n", (int)sizeof(test4));
    printf("sizeof(PMS5)     = %d\n", (int)sizeof(PMS5));
    printf("sizeof(A8MS6)    = %d\n", (int)sizeof(A8MS6));
    printf("sizeof(A2MS7)    = %d\n", (int)sizeof(A2MS7));
    printf("sizeof(A32MS8)   = %d\n", (int)sizeof(A32MS8));
    return 0;
}

#include <stdio.h>
typedef struct struct_test1
{
    int a;   // 4 
    double b;  // 8
}ST1;
int main(void)
{
    printf("__alignof(char ) = %d\n", __alignof(char ));  //1
    printf("__alignof(short ) = %d\n", __alignof(short ));  //2
    printf("__alignof(int ) = %d\n", __alignof(int ));  //4
    printf("__alignof(long ) = %d\n", __alignof(long ));  //8
    printf("__alignof(long long) = %d\n", __alignof(long long )); //8
    printf("__alignof(float ) = %d\n", __alignof(float ));  // 4
    printf("__alignof(double ) = %d\n", __alignof(double )); //8
    printf("__alignof(ST1 ) = %d\n", __alignof(ST1 )); //8  ???????

    return 0;
}

__alignof操作返回数据类型或者指定数据项的分界对齐。实际上的数据对齐根据硬件系统不同而不同,因为该需求是由机器设置的

__attribute__与变量

C/C++中长度为n字节的基本数据类型的变量在编译时会被编译器默认分配到n字节对齐的内存上。例如,int的长度是4字节,所以int类型变量将被分配到4字节对齐的地址上。我们也可以通过__attribute__((aligned(n)))来改变这种默认状态。

int a __attribute__ ((aligned (16))) = 0;

这样就把a分配到了16字节对齐的地址上。

__attribute__与函数

和改变变量的默认对齐状态一样,也可以通过__attribute__((aligned(n)))来改变函数的自然对齐状态。

void __attribute__ ((aligned (64))) func(void)
{
    /*功能实现代码*/
}

  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值