浅析C语言中的weak symbol

2019-05-16  本文已影响0人  时光旧白

在Linux开发环境中,有强符号和弱符号,符号简单来说就是函数、变量的名字,对于全局(非局部、非static)的函数和变量,能不能重名是有一定规矩的,强、弱符号就是针对这些全局函数和变量来说的。

强符号与弱符号

在C语言中,函数和初始化的全局变量(包括显示初始化为0)是强符号,未初始化的全局变量是弱符号。其规则如下:

声明弱符号

弱符号的声明可采用两种方式:

void __attribute__((weak)) func(void)
or
__attribute__((weak)) void func(void)
or
void func(void)__attribute__((weak))
#pragma weak func

举个例子

main.c

#include <stdio.h>

void __attribute__((weak)) func(void)
{
    printf("Can't find the define of %s!\n", __FUNCTION__);
}

int main(int argc, char **argv)
{
    func();
    return 0;
}

编译输出:

$ gcc main.c -o test && ./test
Can't find the define of func!

Note:对于上述函数的声明,还可以这样写:

void __attribute__((weak)) func(void);
void func(void)
{
  printf("Can't find the define of %s!\n", __FUNCTION__);
}

还可以这样写:

void func(void)__attribute__((weak));
void func(void)
{
  printf("Can't find the define of %s!\n", __FUNCTION__);
}

但是下面的写法就是导致编译失败:

void func(void)__attribute__((weak))
{
  printf("Can't find the define of %s!\n", __FUNCTION__);
}

func.c

#include <stdio.h>

void func(void)
{
    printf("I‘m the define of %s!\n", __FUNCTION__);
}

编译输出:

$ gcc main.c func.c -o test && ./test
I'm the define of func!

结论:同名函数的强符号和弱符号同时存在时,以强符号为准,弱符号失去作用。因此在实际开发中,若函数func还未ready,在调用func函数的主函数中对其声明为__attribute__((weak))后可以使主函数编译通过,否则主函数因无法link函数func而编译失败。

__weak的含义

有时候在代码中可以看到会用到__weak,其实__weak是一个宏定义,在Linux代码中可以见其定义在include/linux/compiler_attributes.h中:

#define   __weak   __attribute__((weak))

它常用于函数和变量的声明和函数的定义,是GNU compiler的扩展,被ARM compiler支持,可以将一个函数声明为weak,当没有其他同名函数声明时调用weak,有其他同名函数时调用其他同名函数。

上一篇下一篇

猜你喜欢

热点阅读