• __attribute__((packed))详解


    1. __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编译器来击活该功能,这是控制警告信息的一个很好的方式。

    2. packed属性:packed是类型属性(Type Attribute)的一个参数,使用packed可以减小对象占用的空间。使用该属性可以使得变量或者结构体成员使用最小的对齐方式,即对变量是一字节对齐,对域(field)是位对齐。

    __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

    使用该属性对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__,来决定是否使用内存对齐,或是内存对齐到几个字节:

    #include <stdio.h>
    
    //到4字节,同样可指定对齐到8字节
    struct student1
    {
        char name[7];
        unsigned int id;
        char subject[5];
    } __attribute__ ((aligned(4))); 
    
    //不对齐,结构体的长度,就是各个变量长度的和
    struct student2
    {
        char name[7];
        unsigned int id;
        char subject[5];
    } __attribute__ ((packed));
    
    int main(){
    
      printf("%d\n", sizeof(struct student1));  //20
      printf("%d\n", sizeof(struct student2));  //16
    }
  • 相关阅读:
    如何轻松的从GAC文件夹拷贝dll出来
    UIManager的用法(用于改变界面风格)
    Java休眠睡眠方法
    Thread.currentThread().getContextClassLoader()与Test.class.getClassLoader()的区别
    Openfire编译命令
    Openfire插件开发
    通过Java代码打开浏览器,本地文件目录以及ftp站点
    使用Pack200压缩你的代码
    Java 创建文件与创建文件夹
    Openfire插件制作
  • 原文地址:https://www.cnblogs.com/beanmoon/p/2741920.html
Copyright © 2020-2023  润新知