• GNU C语法扩展(10)


    6217760-e609897bd82c4891.png

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

    10、内建函数

    GNU C提供了大量的内建函数,其中很多是标准C库函数的内建版本,例如memcpy,它们与对应的C库函数功能相同,本文不讨论这类函数,其他内建函数的名字通常以__builtin开始。

    • 内建函数__builtin_return_address(LEVEL)返回当前函数或其调用者的返回地址,参数LEVEL指定调用栈的级数,如0表示当前函数的返回地址,1表示当前函数调用者的返回地址,依此类推。例
      如:
    //kernel/sched.c
    printk(KERN_ERR "schedule_timeout: wrong timeout" "value %lx from %p
    ", timeout, __builtin_return_address(0));
    
    • 内建函数__builtin_constant_p(EXP)用于判断一个值是否为编译时常数,如果参数EXP的值是常数,函数返回1,否则返回0。
    //include /asm-i386/bitops.h
    #define test_bit(nr,addr)/
        (__builtin_constant_p(nr)?/
        constant_test_bit( (nr),(addr) ):/
        variable_test_bit( (nr),(addr) ) )
    

    很多计算或操作在参数为常数时有更优化的实现,在GNUC中用上面的方法可以根据参数是否为常数,只编译常数版本或非常数版本,这样既不失通用性,又能在参数是常数时编译出最优化的代码。

    • 内建函数__builtin_expect(EXP, C)用于为编译器提供分支预测信息,其返回值是整数表达式EXP的值,C的值必须是编译时常数。例如:
    //include /linux/compiler.h
    #define likely(x) __builtin_expect((x),1)
    #define unlikely(x) __builtin_expect((x),0)
    
    //kernel/sched.c
    if( unlikely(in_interrupt()) ){
        printk("Schedulingininterrupt/n");
        BUG();
    }
    

    这个内建函数的语义是EXP的预期值是C,编译器可以根据这个信息适当地重排语句块的顺序,使程序在预期的情况下有更高的执行效率。上面的例子表示处于中断上下文是很少发生的,第6-7行的目标码可能会放在较远的位置,以保证经常执行的目标码更紧凑。
    若不想使用GNUC扩展,那么只需要在gcc参数后面加上-ansi-pedantic即可,使用上述参数后,所有GNCC扩展语法部分将会有编译警报。

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

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

    或扫描二维码:

    6217760-e6bba06e005d8fe7.jpg

  • 相关阅读:
    ubuntu12.04.2上利用cmake安装opencv2.4.6
    微软无线鼠标3500滚轮问题
    Linux 安装 Tomcat
    Linux 安装 MySQL
    Linux 安装 JDK
    Linux 安装 Redis 及踩坑
    IDEA Git 撤销push(回退到指定版本)
    【Java】Ajax实现级联城市
    node.js更换镜像源
    【Java】数据库连接池的简单使用
  • 原文地址:https://www.cnblogs.com/leon1124/p/14039784.html
Copyright © 2020-2023  润新知