使用__attribute__处理结构对齐问题
来源:互联网 发布:php is numeric 编辑:程序博客网 时间:2024/06/08 01:36
GNU C扩展的__attribute__ 机制被用来设置函数、变量、类型的属性,其用得较多的是处理字节对齐的问题。
__attribute__ 的语法为:
参数aligned(number) [number为最小对齐的字节数]是用得较多的一个。
另一个是参数packed 表示“使用最小对齐”方式,即对变量是字节对齐,对于域是位对齐。
这个例子稍长了点,不过非常简单:
[root@Kendo develop]# cat align.c
CODE:
#include <stdio.h>
struct A{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
};
struct B{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
}__attribute__((aligned));
struct C{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
}__attribute__((aligned(1)));
struct D{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
}__attribute__((aligned(4)));
struct E{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
}__attribute__((aligned(8)));
struct F{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
}__attribute__((packed));
int main(int argc, char **argv)
{
printf("A = %d, B = %d, C = %d, D = %d, E = %d, F = %d/n",
sizeof(struct A), sizeof(struct B), sizeof(struct C), sizeof(struct D), sizeof(struct E), sizeof(struct F));
return 0;
}
在一个32位机上运行结果如下:
CODE:
[root@Kendo develop]# gcc -o align align.c
[root@Kendo develop]# ./align
A = 28, B = 32, C = 28, D = 28, E = 32, F = 20
我们看到,最后一个struct F,1 + 4 + 2 + 4 + 8 + 1 = 20,因为使用了__attribute__((packed)); 来表示以最小方式对齐,所以结果刚好为20。
而第一个struct A,因为什么也没有跟,采用默认处理方式:4(1) + 4 + 4(2) + 4 + 8 + 4(1) = 28,括号中是其成员本来的大小。与此相似的是struct D。
接下来看struct E,采用8个字节的方式来对齐:8(1+4+2 ,即a, b, c)+ 8(4, d) + 8 + 8(1, f) = 32。
而在struct C中,试图使用__attribute__((aligned(1))) 来使用1个字节方式的对齐,不过并未如愿,仍然采用了默认4个字节的对齐方式。
在struct B中,aligned没有参数,表示“让编译器根据目标机制采用最大最有益的方式对齐"——当然,最有益应该是运行效率最高吧,呵呵。其结果是与struct E相同。
在对结构的大小并不关注的时候,采用默认对齐方式或者编译器认为最有益的方式是最常见的,然后,对于一些对结构空间大小要求严格,例如定义一个数据包报头的时候,明白结构的对齐方式,就非常有用了。
__attribute__ 的语法为:
CODE:
__attribute__ ((语法列表))参数aligned(number) [number为最小对齐的字节数]是用得较多的一个。
另一个是参数packed 表示“使用最小对齐”方式,即对变量是字节对齐,对于域是位对齐。
这个例子稍长了点,不过非常简单:
[root@Kendo develop]# cat align.c
CODE:
#include <stdio.h>
struct A{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
};
struct B{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
}__attribute__((aligned));
struct C{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
}__attribute__((aligned(1)));
struct D{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
}__attribute__((aligned(4)));
struct E{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
}__attribute__((aligned(8)));
struct F{
char a;
int b;
unsigned short c;
long d;
unsigned long long e;
char f;
}__attribute__((packed));
int main(int argc, char **argv)
{
printf("A = %d, B = %d, C = %d, D = %d, E = %d, F = %d/n",
sizeof(struct A), sizeof(struct B), sizeof(struct C), sizeof(struct D), sizeof(struct E), sizeof(struct F));
return 0;
}
在一个32位机上运行结果如下:
CODE:
[root@Kendo develop]# gcc -o align align.c
[root@Kendo develop]# ./align
A = 28, B = 32, C = 28, D = 28, E = 32, F = 20
我们看到,最后一个struct F,1 + 4 + 2 + 4 + 8 + 1 = 20,因为使用了__attribute__((packed)); 来表示以最小方式对齐,所以结果刚好为20。
而第一个struct A,因为什么也没有跟,采用默认处理方式:4(1) + 4 + 4(2) + 4 + 8 + 4(1) = 28,括号中是其成员本来的大小。与此相似的是struct D。
接下来看struct E,采用8个字节的方式来对齐:8(1+4+2 ,即a, b, c)+ 8(4, d) + 8 + 8(1, f) = 32。
而在struct C中,试图使用__attribute__((aligned(1))) 来使用1个字节方式的对齐,不过并未如愿,仍然采用了默认4个字节的对齐方式。
在struct B中,aligned没有参数,表示“让编译器根据目标机制采用最大最有益的方式对齐"——当然,最有益应该是运行效率最高吧,呵呵。其结果是与struct E相同。
在对结构的大小并不关注的时候,采用默认对齐方式或者编译器认为最有益的方式是最常见的,然后,对于一些对结构空间大小要求严格,例如定义一个数据包报头的时候,明白结构的对齐方式,就非常有用了。
- 使用__attribute__处理结构对齐问题
- 使用__attribute__处理对齐问题
- 使用__attribute__处理对齐问题
- 转:使用__attribute__处理对齐问题
- 使结构体紧凑对齐:__attribute__ ((packed))
- 再谈:自定义结构体的对齐问题之__attribute__ ((packed))方法
- #pragma pack,__attribute__选项和结构体对齐相关问题详解
- 使用 __attribute__ ((packed))让结构体编译时内存不对齐
- 使用gcc中的__attribute__指定字节对齐
- 结构体字节对齐,pragma pack,__attribute__(packed)
- 结构体字节对齐,pragma pack,__attribute__(packed)
- 结构体对齐问题.
- 结构体对齐问题
- 结构体对齐问题
- 结构体对齐问题
- 结构体对齐问题
- 结构体对齐问题
- 结构体对齐问题
- JSP学习记--04(Jsp内置对象response/session)
- 搜索启示录—关于垂直搜索的探讨(爱游泳的鱼/sina's blog)
- [转]制作Docbook文档
- 0803代码
- Linux那些事儿之我是U盘(52)有多少爱可以胡来?(一)
- 使用__attribute__处理结构对齐问题
- VC获得系统文件夹路径
- 比尔.盖茨终于毕业了
- mysql安装错误!
- 《黑vip光盘全集 价值千元》
- Java学习方法漫谈(一)
- 四天oracle亚太地区体会
- C语言版的线性回归分析函数
- 获得当然前应用程序路径