gcc强引用弱引用

强符号和弱符号

多个目标文件中含有相同名字全局符号的定义,那么这些目标文件链接的时候将会出现符号重复定义的错误.编译器默认函数和初始化了的全局变量为强符号(Strong Symbol),未初始化的全局变量为弱符号(Weak Symbol),强弱符号都是针对定义来说的,不是针对符号的引用(extern int ext);

链接器处理符号规则:

  1. 不允许强符号被多次定义(即不同的目标文件中不能有同名的强符号),如果有多个强符号的定义,则链接器报符号重定义错误
  2. 如果一个符号在某个目标文件中是强符号,但是在其他文件中都是弱符号,那么选择强符号
  3. 一个符号在所有的目标文件中都是弱符号,选择其中占用空间最大的一个

实例:

1
2
3
4
5
6
7
8
9
10
11
12
//test.c 
#include <stdio.h>

void __attribute__((weak)) weak_func(void)
{
printf("default weak func is running\n");
}

void test_func(void)
{
weak_func();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>

void test_func(void);

/*
void weak_func(void)
{
printf("custom strong func override!\n");
}
*/

int main()
{
test_func();
return 0;
}

当main.c中的定义了weak_func()函数(强符号)时,则会覆盖test.c的弱符号

1
2
gcc test.c main.c -o main 
./main

强引用和弱引用

链接器处理强引用 和 弱引用的过程一样,

强引用(Strong Reference): 对外部目标文件的符号引用在目标文件被最终链接成可执行文件时,必须被正确决议,如果没有找到该符号的定义,链接器报符号未定义的错误.

弱引用(Weak Reference): 对于未定义的弱引用,链接器不认为是错误,链接器默认为0,(或特数值)

弱引用例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//main.c 
#include <stdio.h>
#include <pthread.h>

extern int func(int);

static int testSymbol(int) __attribute__((weakref("func")));

int main()
{
if (testSymbol)
{
testSymbol(100);
}
else
{
printf("null\n");
}
return 0;
}
1
2
3
4
5
6
7
//test.c
#include <stdio.h>

int func(int a)
{
printf("func(%d)\n",a);
}

gcc main.c test.c -o test

./test,可以看到弱引用相当于另一个函数名


__attribute__中 weakref用法

参考文章1


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!