gcc内置函数
来源:互联网 发布:英翻汉软件 编辑:程序博客网 时间:2024/05/19 22:24
一 概要
- 首先内置函数并不是c标准定义的,而是由编译器自定义的。gcc实现了一套自己的内置函数:
https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#Other-Builtins
其中需要引起注意的一段话是:
GCC built-in functions are always expanded inline and thus do not have corresponding entry points and their address cannot be obtained. Attempting to use them in an expression other than a function call results in a compile-time error
可见所有的内置函数都是inline的。
- 内置函数分为两类:
- 内置函数名称:
- 内置函数使用方法:
- 内置函数开关
-fbuiltin:
这是默认选项,用于通过名字来识别内建函数
-fno-builtin:
除非利用前缀 __builtin_ 进行引用,否则不识别所有内建函数。例如,为了获得内建版本,应该调用 __builtin_strcpy() 而不是名为 strcpy() 的函数。
-fno-builtin-xxx(例如:-fno-builtin-fgets):
想使用除fgets() 之外的所有内建函数
二 实现原理
- 内置函数是如何实现的呢?
这个问题看一下gcc的源代码就知道了,或者干脆看一下patch文件:
https://gcc.gnu.org/ml/gcc-patches/2009-06/msg00419.html
打上patch后重新编译gcc,通过这个过程不难发现,其实gcc内置函数跟关键字很相似,在调用内置函数处根据对应的上下文产生不同的代码。
- 内置函数是如何链接的?
- 内置函数都可以通过库函数去实现么?
三 常用built-in函数介绍
- __builtin_constant_p(x)
- __builtin_expect (long exp, long c)
# define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0)
likely和unlikely在内核代码中被大量使用,用来引导gcc进行条件分支预测。在一条指令执行时,由于流水线的作用,CPU可以完成下一条指令的取指,这样可以提高CPU的利用率。在执行一条条件分支指令时,CPU也会预取下一条执行,但是如果条件分支跳转到了其他指令,那CPU预取的下一条指令就没用了,这样就降低了流水线的效率。__builtin_expect(!!(x), 1)返回值!!(x),并使指令尽量顺序执行。
- __builtin_return_address(n)
- __builtin_object_size(const void * ptr, int type)
type is an integer constant from 0 to 3. If the least significant bit is clear, objects are whole variables, if it is set, a closest surrounding subobject is considered the object a pointer points to. The second bit determines if maximum or minimum of remaining bytes is computed.
最低位为0,返回整个object的大小,为1,返回subobject的大小,下面例子能很好的说明:
struct V { char buf1[10]; int b; char buf2[10]; } var;char *p = &var.buf1[1], *q = &var.b;/* Here the object p points to is var. */assert (__builtin_object_size (p, 0) == sizeof (var) - 1);/* The subobject p points to is var.buf1. */assert (__builtin_object_size (p, 1) == sizeof (var.buf1) - 1)如果ptr能够同时指向多个对象,并且都在编译器可确定,则第二位为1返回最大的object大小,为0返回最小的object大小。
但是如果ptr指向的对象在编译期是不确定的,则:
If there are any side-effects in them, it returns (size_t) -1 for type 0 or 1 and (size_t) 0 for type 2 or 3.
关于__builtin_object_size()函数的应用,下面的例子:
#undef memcpy#define bos0(dest) __builtin_object_size (dest, 0)#define memcpy(dest, src, n) \ __builtin___memcpy_chk (dest, src, n, bos0 (dest))char *volatile p;char buf[10];/* It is unknown what object p points to, so this is optimized into plain memcpy - no checking is possible. */memcpy (p, "abcde", n);/* Destination is known and length too. It is known at compile time there will be no overflow. */memcpy (&buf[5], "abcde", 5);/* Destination is known, but the length is not known at compile time. This will result in __memcpy_chk call that can check for overflow at run time. */memcpy (&buf[5], "abcde", n);/* Destination is known and it is known at compile time there will be overflow. There will be a warning and __memcpy_chk call that will abort the program at run time. */memcpy (&buf[6], "abcde", 5);
另外,开源软件中比较常用的应用:-D_FORTIFY_SOURCE=1执行编译期内存越界检查,不影响程序的行为,-D_FORTIFY_SOURCE=2执行更严格的内存检查,可能会导致编译或运行错误。
四 优缺点
优点:方便编程,优化程序运行效率,增强安全检查;
缺点:程序移植性差,gcc之外的编译器可能编译不过,低版本的gcc同样可能出现编译错误。
- gcc内置函数
- gcc内置函数
- gcc内置原子操作函数
- 四种GCC内置位运算函数
- GCC内置原子内存存取函数
- 四种GCC内置位运算函数
- 四种GCC内置位运算函数
- GCC 处理二进制位的内置函数
- 介绍四种GCC内置位运算函数
- 介绍四种GCC内置位运算函数
- 介绍四种GCC内置位运算函数
- 介绍四种GCC内置位运算函数
- 【转】Linux下GCC内置原子操作函数
- 介绍四种GCC内置位运算函数
- 介绍四种GCC内置位运算函数
- 显示gcc内置宏
- 显示gcc内置宏
- 内置函数
- vs生成qt moc文件
- Dex2Oat源码流程(1)——Android6.0
- Centos7配置phpmyadmin用户名认证auth_basic
- 软件架构的触碰
- 是的,这是致远兄弟的第一篇文章,我们在创造一个全新的职业。
- gcc内置函数
- Ubuntu16.04 安装Nodejs
- Elasticsearch API 基本使用
- Model/View之子类化QAbstractItemModel实现QTreeView的复选框
- 一直都用忙来懒惰自己
- 剑指offer——第一个只出现一次的字符(思路很基础,但有个方法比较巧妙)
- SpringMVC重要接口(一)HandlerMethodArgumentResolver
- iOS条件编译
- SystemError: could not open configuration file `/etc/libuser.conf': 没有那个文件或目录