字节对齐问题

gcc之__attribute__简介及对齐参数介绍

GNU C的一大特色就是__attribute__机制。__attribute__机制可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。

  __attribute__语法格式为:__attribute__((attribute-list))。

__attribute__对结构体(struct)或共用体(union)进行属性设置:

  大致有六个参数值可以被设定,即:aligned,packed,transparent_union,deprecated和may_alias。

  在使用__attribute__参数时,你也可以在参数的前后都加上“__”(两个下划线),例如,使用__aligned__而不是aligned,这样,你就可以在相应的头文件里使用它而不需要关心头文件里是否有重名的宏定义。

         如上所述,你可以手动指定对齐的格式,同样,你也可以使用默认的对齐方式。如果aligned后面不指定数值,那么编译器将依据你的目标机器情况使用最大最有益的对齐方式。

为什么需要内存对齐?

    • CPU对内存的读取不是连续的,而是分块读取的,块的大小只能是1、2、4、8、16字节
    • 当读取操作的数据未对齐,则需要两次总线周期来访问内存,因此性能会大打折扣
    • 某些硬件平台只能从规定的地址处取某些特定类型的数据,否则则抛出硬件异常  

下面以目标机32位为例(4字节)

 (1). __attribute__ ((packed))   等价于 __attribute__((packed,aligned(1)))   以一个字节对齐

 struct __attribute__ ((packed)) s1 {
       char a;       // 1 个字节
       int i ;       // 4个字节
  };

 (2). __attribute__((packed,aligned(n))) 以n个字节对齐,n=1/2/4/8/16

struct __attribute__((packed,aligned(4))) s2 {
        char a;       // 1 个字节
        int i ;       // 4个字节
};

 (3).

     #pragma pack(n)   //以n个字节对齐,n=1/2/4/8/16
     struct s4 {
          char a;   // 1 个字节
          int i;      // 4 个字节
          char b;   // 1 个字节
     };
    #pragma pack()

 

下面这个例子以32位目标机为例:

#include <stdio.h>
#include <stdlib.h>
struct s0 {
     char a;   //1个字节
     int  i;  //4个字节
};

struct __attribute__ ((packed)) s1 {
   char a;  //1个字节
   int i ;  //4个字节
};

struct __attribute__((packed,aligned(4))) s2 {
   char a;   //1个字节
   int i ;  //4个字节
};

#pragma pack(1)
struct s3 {
    char a; //1个字节
    int i;  //4个字节
    char b; //1个字节
};
#pragma pack()

#pragma pack(4)
struct s4 {
    char a;  //1个字节
    int i; //4个字节
    char b;  //1个字节
};
#pragma pack()

int main( int argc, char* argv[] ) 
{
  int i;
  struct s0 s_0;    //    默认对齐
  struct s1 s_1;
  struct s2 s_2;
  struct s3 s_3;
  struct s4 s_4;
  printf( " 默认对齐: sizeof s0 is %d\n" , sizeof(s_0) );
  printf( "sizeof s1 is %d\n" , sizeof(s_1) );
  printf( "sizeof s2 is %d\n" , sizeof(s_2) );
  printf( "sizeof s3 is %d\n" , sizeof(s_3) );
  printf( "sizeof s4 is %d\n" , sizeof(s_4) );

  return( 0 );
}

 

tb@tb:~   gcc -o test test.c

tb@tb:~    ./test

最后的结果:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值