#pragma pack(n)和__attribute__((aligned(m)))的区别

来源:互联网 发布:sim卡apdu数据 编辑:程序博客网 时间:2024/06/05 14:48

    前者告诉编译器结构体或类内部的成员变量相对于第一个变量的地址的偏移量的对齐方式,缺省情况下,编译器按照自然边界对齐,当变量所需的自然对齐边界比n大 时,按照n对齐,否则按照自然边界对齐;后者告诉编译器一个结构体或者类或者联合或者一个类型的变量(对象)分配地址空间时的地址对齐方式。

    也就是所,如 果将__attribute__((aligned(m)))作用于一个类型,那么该类型的变量在分配地址空间时,其存放的地址一定按照m字节对齐(m必 须是2的幂次方)。并且其占用的空间,即大小,也是m的整数倍,以保证在申请连续存储空间的时候,每一个元素的地址也是按照m字节对齐。 __attribute__((aligned(m)))也可以作用于一个单独的变量。举例说明:

#include<stdio.h>

#pragma pack(push) //保存之前的对齐状态

#pragma pack(4)  //设置4字节对齐

typedef struct{

uint32_t f1;

uint8_t f2;

uint8_t f3;

uint32_t f4;

uint64_t f5;

}__attribute__((aligned(1024))) ts;

#pragma pack(pop) //恢复对齐状态

int main()

{

printf("Struct size is: %d, aligned on 1024\n",sizeof(ts));

printf("Allocate f1 on address: 0x%x\n",&(((ts*)0)->f1));

printf("Allocate f2 on address: 0x%x\n",&(((ts*)0)->f2));

printf("Allocate f3 on address: 0x%x\n",&(((ts*)0)->f3));

printf("Allocate f4 on address: 0x%x\n",&(((ts*)0)->f4));

printf("Allocate f5 on address: 0x%x\n",&(((ts*)0)->f5));

return 0;

}

输出:

Struct size is: 1024, aligned on 1024

Allocate f1 on address: 0x0

Allocate f2 on address: 0x4

Allocate f3 on address: 0x5

Allocate f4 on address: 0x8

Allocate f5 on address: 0xc

注意

绿色部分表明了__attribute__((aligned(1024))) 的作用

红色部分说明#pragma pack(4)只对大小大于4的成员变量的地址偏移起作用

紫色部分说明对于大小大于4的成员变量,其地址偏移按照4字节对齐


注: pragma作用于结构内的成员变量,这个是有条件的,只有当成员变量大小 >= pragma设置的大小时,这个约束才起作用,否则按默认的对齐方式,如上面的例子: pragma设置为4,但char类型的成员占用的内存<4,按默认的对齐方式,即1字节对齐;attribute ((aligned(n)))作用于结构体分配地址的对齐方式 和 结构体的大小。

0 0
原创粉丝点击