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

  • 相关阅读:
    237. Delete Node in a Linked List
    430. Flatten a Multilevel Doubly Linked List
    707. Design Linked List
    83. Remove Duplicates from Sorted List
    160. Intersection of Two Linked Lists
    426. Convert Binary Search Tree to Sorted Doubly Linked List
    142. Linked List Cycle II
    类之间的关系
    初始化块
    明确类和对象
  • 原文地址:https://www.cnblogs.com/leon1124/p/14039786.html
Copyright © 2011-2022 走看看