zoukankan      html  css  js  c++  java
  • GNU C语法扩展(9)

    6217760-e609897bd82c4891.png

    要研究LINUX内核,C语言是基础中的基础,但是LINUX并不是完全的标准C,而是对标准C做了很多扩展,这些扩展特性对于我们分析内核有着很重要的作用,下面做些总结性的工作。

    9、特殊属性声明

    GNU C允许声明函数、变量和类型的特殊属性,以便进行手工的代码优化和定制代码检查的方法。

    • no return属性用于函数,表示该函数从不返回。这可以让编译器生成稍微优化的代码,最重要的是可以消除不必要的警告信息比如未初使化的变量。例如:
    //include/linux/kernel.h
    #define ATTRIB_NORET __attribute__((noreturn))...
    asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET;
    
    • format(ARCHETYPE,STRING-INDEX,FIRST-TO-CHECK)属性用于函数,表示该函数使用
      printf,scanf或strftime风格的参数,使用这类函数最容易犯的错误是格式串与参数不匹配,指定format属性可以让编译器根据格式串检查参数类型。例如:
    //include/linux/kernel.h
    asm linkage int printk(const char* fmt, ...)__attribute__((format(printf,1,2)));
    

    表示第一个参数是格式串,从第二个参数起根据格式串检查参数。

    • unused属性用于函数和变量,表示该函数或变量可能不使用,这个属性可以避免编译器产生警告信息。

    • section("section-name")属性用于函数和变量,通常编译器将函数放在.text区,变量放在.data区或.bss区,使用section属性,可以让编译器将函数或变量放在指定的节中。例如:

    //include/linux/init.h
    #define __init __attribute__((__section__(".text.init")))
    #define __exit __attribute__((unused,__section__(".text.exit")))
    #define __init data__attribute__((__section__(".data.init")))
    #define __exit data__attribute__((unused,__section__(".data.exit")))
    
    #define __initsetup __attribute__((unused,__section__(".setup.init")))
    #define __init_call __attribute__((unused,__section__(".initcall.init")))
    #define __exit_call __attribute__((unused,__section__(".exitcall.exit")))
    

    连接器可以把相同节的代码或数据安排在一起,Linux内核很喜欢使用这种技术,例如系统的初始
    化代码被安排在单独的一个节,在初始化结束后就可以释放这部分内存。

    • aligned(ALIGNMENT)属性用于变量、结构或联合类型,指定变量、结构域、结构或联合的对齐量,以字节为单位,例如:
    //include/asm-i386/processor.h
    struct i387_fxsave_struct{
        unsigned short cwd;
        ...
    }__attribute__((aligned(16)));
    

    表示该结构类型的变量以16字节对齐。通常编译器会选择合适的对齐量,显示指定对齐通常是由于体系限制、优化等原因。

    • packed属性用于变量和类型,用于变量或结构域时表示使用最小可能的对齐,用于枚举、结构或联合类型时表示该类型使用最小的内存。例如:
    //include/asm-i386/desc.h
    struct Xgt_desc_struct{
        unsigned short size;
        unsigned long address__attribute__((packed));
    };
    

    域address将紧接着size分配。属性packed的用途大多是定义硬件相关的结构,使元素之间没有因
    对齐而造成的空洞。


    ===========我是华丽的分割线===========


    更多知识:
    点击关注专题:嵌入式Linux & ARM

    或浏览器打开:https://www.jianshu.com/c/42d33cadb1c1

    或扫描二维码:

    6217760-e6bba06e005d8fe7.jpg

  • 相关阅读:
    C++ | 继承(基类,父类,超类),(派生类,子类)
    C++ std::pair的用法
    派生类构造函数和多重继承的二义性问题
    C++vector and opencv Mat
    C++中union的使用方法
    C++中数组作为形参的方法
    在Python中使用OpenCV(CV2)对图像进行边缘检测
    你可能会用到的一些小程序效果、工具
    AI口算批改、练习小程序
    拍照搜题小程序
  • 原文地址:https://www.cnblogs.com/leon1124/p/14039786.html
Copyright © 2011-2022 走看看