现在的位置: 首页 > 技术文章 > 正文

__attribute__ 之weak,alias属性

2018年05月30日 技术文章 ⁄ 共 1101字 ⁄ 字号 __attribute__ 之weak,alias属性已关闭评论 ⁄ 阅读 1,725 次

Weak Alias 是 gcc 扩展里的东西,实际上是函数的属性。这个东西在库的实现里面可能会经常用到,比如 glibc 里面就用了不少。抄录一段 gcc 手册里面的话解释下函数属性是干啥的

In GNU C, you declare certain things about functions called in your program which help the compiler optimize function calls and check your code more carefully.

先上代码,看看 weak alias 怎么写。

第一个文件 dummy.c 内容


int __foo()

{

puts(”I do no thing.”);

}

int foo() __attribute__ ((weak,alias(”__foo”)));

weak 和 alias 分别是两个属性。weak 使得 foo 这个符号在目标文件中作为 weak symbol 而不是 global symbol。用 nm 命令查看编译 dummy.c 生成的目标文件可用看到 foo 是一个 weak symbol,它前面的标记是 W。给函数加上weak属性时,即使函数没定义,函数被调用也可以编译成功。


00000000 T __foo 00000000 W foo U puts

而 alias 则使 foo 是 __foo 的一个别名,__foo 和 foo 必须在同一个编译单元中定义,否则会编译出错。

那么这个东西的用处是?

看第二个文件,func.c,


int foo()

{

puts(”I do something.”);

}

这里有一个函数名字是 foo。如果我们编译 func.c 和 dummy.c 得到两个目标文件,当我们同时使用 func.o 和 dummy.o 和其他目标文件进行链接时,如果其他目标文件里面引用符号 foo,最终使用到的是 func.c 中定义的函数,而不是 dummy.c中的__foo,虽然它有一个别名 foo。也就是说,我们最终使用到的函数会是“I do something”的那个函数。

当然,单独使用 dummy.o 链接的话使用的是那个“I do no thing”的函数。如果 dummy.o 中的 foo 不是 weak symbol 的话,在链接时会产生冲突,这就是我们要使用 weak 的原因。

弱符号:

若两个或两个以上全局符号(函数或变量名)名字一样,而其中之一声明为weak symbol(弱符号),则这些全局符号不会引发重定义错误。链接器会忽略弱符号,去使用普通的全局符号来解析所有对这些符号的引用,但当普通的全局符号不可用时,链接器会使用弱符号。当有函数或变量名可能被用户覆盖时,该函数或变量名可以声明为一个弱符号。

gnu

×