Linux内建函数

  GNU C提供了大量内建函数,其中大部分是标准C库函数的GNU C编译器内建版本,例如memcpy()等,它们与对应的C库函数功能相同。

  不属于库函数的其它内建函数的命名通常以__builtin开始,如下所示:

  • 内建函数__builtin_return_address(LEVEL)返回当前函数或其调用者的返回地址。参数LEVEL指定调用栈的级数,如0表示当前函数的返回地址,1表示当前函数调用者的返回地址。
  • 内建函数__builtin_constant_p(EXP)用于判断一个值是否为编译时常数,如果参数EXP的值是常数,函数返回1,否则返回0。

  例如,下面的代码可检测第1个参数是否为编译时常数以确定采用参数版本还是非参数版本:

Linux内建函数
1 #define test_bit(nr, addr) 2     (__builtin_constant_p(nr)) ? 3     constant_test_bit((nr), (addr)) : 4     variable_test_bit((nr), (addr)))
View Code
  • 内建函数__builtin_expert(EXP, C)用于为编译器提供分支预测信息,其返回值是整数表达式EXP的值,C的值必须是编译时常数。

  Linux内核编程时常用的likely()和unlikely()底层通用的likely_notrace()、unlikely_notrace()就是基于__builtin_expect(EXP, C)实现的。

Linux内建函数
1 #define likely_notrace(x)     __bulitin_expert(!!(x), 1)
2 #define unlikely_notrace(x) __bulitin_expert(!!(x), 0)
View Code

  若代码中出现分支,则即可能中断流水线,我们可以通过likely()和unlikely()暗示分支容易成立还是不容易成立,例如

Linux内建函数
1 if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev))) 
2     if (ipv4_is_loopback(saddr))
3         goto e_inval;
View Code

  在使用gcc编译C程序的时候,如果使用“-ansi-pedantic”编译选项,则会告诉编译器不使用GNU扩展语法。例如对于如下C程序test.c:

Linux内建函数
1 struct var_data {
2     int len;
3     char data[0];
4 };
View Code

  struct var_data a;

  直接编译通过;

  如果使用“-ansi-pedantic”编译选项,编译会报警:

  gcc -ansi -pedantic -c test.c

  test.c:3: warning: ISO C forbids zero-size array ‘data‘

Linux内建函数

上一篇:Linux磁盘


下一篇:Mac小技巧 | 如何在 Touch Bar 上显示歌词