1. __attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,是GCC特有的语法。这个功能是跟操作系统没关系,跟编译器有关,gcc编译器不是紧凑模式的,我在windows下,用vc的编译器也不是紧凑的,用tc的编译器就是紧凑的。例如:

在TC下:struct my{ char ch; int a;} sizeof(int)=2;sizeof(my)=3;(紧凑模式)
在GCC下:struct my{ char ch; int a;} sizeof(int)=4;sizeof(my)=8;(非紧凑模式)
在GCC下:struct my{ char ch; int a;}__attrubte__ ((packed)) sizeof(int)=4;sizeof(my)=5
2. __attribute__关键字主要是用来在函数或数据声明中设置其属性。给函数赋给属性的主要目的在于让编译器进行优化。函数声明中的__attribute__((noreturn)),就是告诉编译器这个函数不会返回给调用者,以便编译器在优化时去掉不必要的函数返回代码。
GNU C的一大特色就是__attribute__机制。__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。
__attribute__书写特征是:__attribute__前后都有两个下划线,并且后面会紧跟一对括弧,括弧里面是相应的__attribute__参数。
__attribute__语法格式为:
__attribute__ ((attribute-list))
其位置约束:放于声明的尾部“;”之前。
函数属性(Function Attribute):函数属性可以帮助开发者把一些特性添加到函数声明中,从而可以使编译器在错误检查方面的功能更强大。__attribute__机制也很容易同非GNU应用程序做到兼容之功效。
GNU CC需要使用 –Wall编译器来击活该功能,这是控制警告信息的一个很好的方式。
packed属性:使用该属性可以使得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(field)是位对齐。
如果你看过GPSR协议在TinyOS中的实现,你一定会注意到下面的语句:
typedef struct {
double x;
double y;
} __attribute__((packed)) position_t;
开始我们还可以理解,不久是定义一个结构体嘛!不过看到后面的语句,你可能就会一头雾水了,’ __attribute__((packed))’是什么东西?有什么作用?一连串的疑问马上就会从你脑袋里冒出来。虽然这个对理解整个程序没有什么影响,但我不想让这些疑问一直呆在我的脑子里,负担太重。省得以后念念不忘,而且也许有一天可以用的上呢。搞清楚这个问题吧!
GNU C的一大特色(却不被初学者所知)就是__attribute__机制。__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)。
__attribute__语法格式为:
__attribute__ ((attribute-list))
其位置约束为:放于声明的尾部“;”之前。
packed是类型属性(Type Attribute)的一个参数,使用packed可以减小对象占用的空间。需要注意的是,attribute属性的效力与你的连接器也有关,如果你的连接器最大只支持16字节对齐,那么你此时定义32字节对齐也是无济于事的。
使用该属性对struct或者union类型进行定义,设定其类型的每一个变量的内存约束。当用在enum类型定义时,暗示了应该使用最小完整的类型(it indicates that the smallest integral type should be used)。
下面的例子中,my-packed-struct类型的变量数组中的值会紧凑在一起,但内部的成员变量s不会被“pack”,如果希望内部的成员变量也被packed的话,my-unpacked-struct也需要使用packed进行相应的约束。
struct my_unpacked_struct
{
char c;
int i;
};
struct my_packed_struct
{
char c;
int i;
struct my_unpacked_struct s;
}__attribute__ ((__packed__));
在每个系统上看下这个结构体的长度吧。
内存对齐,往往是由编译器来做的,如果你使用的是gcc,可以在定义变量时,添加__attribute__,来决定是否使用内存对齐,或是内存对齐到几个字节,以上面的结构体为例:
1)到4字节,同样可指定对齐到8字节。
struct student
{
char name[7];
uint32_t id;
char subject[5];
} __attribute__ ((aligned(4))); 
2)不对齐,结构体的长度,就是各个变量长度的和
struct student
{
char name[7];
uint32_t id;
char subject[5];
} __attribute__ ((packed));

不同框架的处理器对齐方式会有不同,这个时候不指定对齐的话,会产生错误结果
跨平台通信时用到。不同平台内存对齐方式不同。
如果使用结构体进行平台间的通信,会有问题。
例如,发送消息的平台上,结构体为24字节,接受消息的平台上,此结构体为32字节(只是随便举个例子),那么每个变量对应的值就不对了。
网络通信通常分为基于数据结构的和基于流的。HTTP协议就是后者的一个例子。
??? 有时为了提高程序的处理速度和数据处理的方便,会使用基于数据结构的通信(不需要对流进行解析)。但是,当需要在多平台间进行通信时,基于数据结构的通信,往往要十分注意以下几个方面:
[1] 字节序
[2] 变量长度
[3] 内存对齐
??? 在常见的系统架构中(Linux X86,Windows),非单字节长度的变量类型,都是低字节在前,而在某些特定系统中,如Soalris Sparc平台,高字节在前。如果在发送数据前不进行处理,那么由Linux X86发向Soalris Sparc平台的数据值,势必会有极大的偏差,进而程序运行过程中无法出现预计的正常结果,更严重时,会导致段错误。
??? 对于此种情况,我们往往使用同一的字节序。在系统中,有ntohXXX(), htonXXX()等函数,负责将数据在网络字节序和本地字节序之间转换。虽然每种系统的本地字节序不同,但是对于所有系统来说,网络字节序是固定的-----高字节在前。所以,可以以网络字节序为通信的标准,发送前,数据都转换为网络字节序。
??? 转换的过程,也建议使用ntohXXX(), htonXXX()等标准函数,这样代码可以轻松地在各平台间进行移植(像通信这种很少依赖系统API的代码,做成通用版本是不错的选择)。
??? 变量的长度,在不同的系统之间会有差别,如同是Linux2.6.18的平台,在64位系统中,指针的长度为8个字节,而在32位系统中,指针又是4个字节的长度---此处只是举个例子,很少有人会将指针作为数据发送出去。下面是我整理的在64位Linux系统和32位Linux系统中,几种常见C语言变量的长度:
??????????????? short??? int??? long??? long long??? ptr??? time_t
32位?????????? 2???????? 4?????? 4???????????? 8?????????????? 4??????? 4
64位?????????? 2???????? 4?????? 8???????????? 8?????????????? 8??????? 8
??? 在定义通信用的结构体时,应该考虑使用定常的数据类型,如uint32_t,4字节的固定长度,并且这属于标准C库(C99),在各系统中都可使用。
??? 内存对齐的问题,也与系统是64位还是32位有关。如果你手头有32位和64位系统,不妨写个简单的程序测试一下,你就会看到同一个结构体,即便使用了定常的数据类型,在不同系统中的大小是不同的。对齐往往是以4字节或8字节为准的,只要你写的测试程序,变量所占空间没有对齐到4或8的倍数即可,举个简单的测试用的结构体的例子吧:
struct student
{
??? char name[7];
??? uint32_t id;
??? char subject[5];
};
??? 在每个系统上看下这个结构体的长度吧。
??? 内存对齐,往往是由编译器来做的,如果你使用的是gcc,可以在定义变量时,添加__attribute__,来决定是否使用内存对齐,或是内存对齐到几个字节,以上面的结构体为例:
?1)到4字节,同样可指定对齐到8字节。
struct student
{
??? char name[7];
??? uint32_t id;
??? char subject[5];
} __attribute__ ((aligned(4)));?
2)不对齐,结构体的长度,就是各个变量长度的和
struct student
{
??? char name[7];
??? uint32_t id;
??? char subject[5];
} __attribute__ ((packed));



转载于:https://blog.51cto.com/heipi/1174666

__attribute__ ((packed))相关推荐

  1. __attribute__((packed))

    1. __attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,是GCC特有的语法.这个功能是跟操作系统没关系,跟编译器有关,g ...

  2. 关于__attribute__ ((packed))

    #include <iostream>using namespace std;typedef struct {unsigned char ver;unsigned char cmd;uns ...

  3. gcc 中的__attribute__ ((packed)) gcc移植,内存对齐.结构体对齐-转

    __attrubte__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐. #define __u8    unsigned char #defi ...

  4. __attribute__((packed)) C

    __attribute__((packed))详解 标签: it 分类: linux程序 1. __attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按 ...

  5. __attribute__((packed))的使用

    一.attribute((packed)) 1.__attrubte__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐.是GCC特有的语法.这个 ...

  6. [zz]GNU C __attribute__ 机制简介

    GNU C的一大特色(却不被初学者所知)就是__attribute__机制.__attribute__可以设置函数属性(Function Attribute).变量属性(Variable Attrib ...

  7. __attribute__ 总结

    attribute是GNU C特色之一,在iOS用的比较广泛.系统中有许多地方使用到. attribute可以设置函数属性(Function Attribute ).变量属性(Variable Att ...

  8. @清晰掉 GNU C __attribute__

    __attribute__((packed))详解 1. __attribute__ ((packed)) 的作用就是告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐,是GCC特有 ...

  9. GNU C __attribute__ 机制简介

    原文链接:http://afreez.blog.51cto.com/59057/7351 摘要: 在学习linux内核代码及一些开源软件的源码(如:DirectFB),经常可以看到有关__attrib ...

最新文章

  1. 健身也内卷?这届网友用 Python 掌握了做标准俯卧撑的秘诀
  2. python恶搞小程序-抖音最火的整蛊表白小程序如何做出来的?教你用python做出
  3. php 多个单选怎么办,【大神看过来】根据一个用PHP做的单选投票,改成多选,且可显示...
  4. c语言,如何产生随机数
  5. 解答:为什么蚊子咬的包会痒痒
  6. Redis 命令字符串(String)
  7. 怎样对ZBrush中的材料进行渲染和着色
  8. iOS sqlite
  9. 前端学习(628):数字类型
  10. java 调用tomcat api,调用servlet接口流程
  11. 开发类似vs的黑色风格_传闻:2020年《使命召唤》将是《黑色行动》重启作品
  12. android 全局定时器,高通Android LED驱动移植-GPIO,内核定时器
  13. 清华学霸直博简历火了:CPU、操作系统、编译器全自己写
  14. UITableView基本用法
  15. Electron 遭封杀,Web 开发者在苹果平台上举步维艰!
  16. matlab语句跳转,matlab编程 跳转语句
  17. (Origin教程)在图片和表格中插入Latex公式
  18. iOS16 beta8 描述文件官方地址下载
  19. 回国后无线网safari无法连接服务器,解决Mac能连上WIFI但无法上网的问题
  20. 股票交易成本有哪些费用?

热门文章

  1. Contact Bubble View
  2. [zt]数学之美番外篇:平凡而又神奇的贝叶斯方法
  3. BEA Workshop Studio有什么用?
  4. 设计模式 — 行为型模式 — 责任链模式
  5. 设计模式 — 创建型模式 — 单例模式
  6. RESTful三理解
  7. ARM 命名规则、架构
  8. Goland实现Set操作
  9. 数值和字符串互相转换
  10. SCOM2016 安装OS或应用管理包