C语言强符号、弱符号问题

C语言强弱符号规则

C语言中,函数和初始化的全局变量(包括显式初始化为0的)都是强符号,未初始化的全局变量是弱符号

  • 同名的强符号只能有一个,如果定义多个强符号则编译器会报错
int a = 1;
char a = 2;
  • 允许有一个强符号和多个弱符号,编译器不报错
int a = 2;
int a;
char a ;
  • 当有多个弱符号,而无强符号的时候,编译器会自动选择占用内存空间最大的那个弱符号,下面例子打印数值应该是8.
double a;
int a;
char a;
printf("sizeof(a) = %d",sizeof(a));

哪些符号是弱符号

  • 为什么会出现重复定义
    出现重复定义原因就是在链接为一个目标文件的时候,发现了多个强符号,编译器/连接器无法确定使用哪一个强符号从而报错
/*A文件*/
int a = 12;
/*B文件*/
char a = 12;

如果将A、B文件同时编译链接到一个目标文件则会报变量重复定义错误,A、B文件中两个变量a都是强符号,因为他们都初始化了,而且都是全局变量。
倘若A文件改为

/*A文件*/
int a;

则A文件中变量则为弱符号,如果重新编译链接A、B则不会出现重复定义的报错,因为此时只有B文件一个a强符号

  • 定义弱符号方式

    1. 由上面的分析可知,在定义多个符号(全局变量)的同时,只要不将其初始化就可以将其定义为弱符号
    2. 。也可以通过GCC的 attribute((weak)) 来定义一个弱符号
extern int extra;
int weak1;
int strong = 1;
int __attribute__((weak)) weak2 = 2;
void __attribute__((weak)) f_week();
void  f_strong(void){
    int a =1;
}
int main()
{
        return 0;
}

可知weak1,weak2,fweek()是弱符号,weak1是没有初始化所以是弱符号,f_week没有初始化使用了GCC弱符号定义前缀是弱符号,weak2即使初始化了由于他的前缀attribute((weak)) 所以仍是弱符号。
f_strong()、main()、strong都是强符号。

  • 弱符号存在的意义是什么
    先来看一段代码,再来问为什么
int main(void)
{
        f();
        return 0;
}

大家都知道这段代码如果单独编译的话是都无法编译成功的
再来看下面代码

void __attribute__((weak)) f_week();
int main(void)
{
        if (f)
        f_week();
        return 0;
}

这段代码不但可以编译成功,甚至可以运行成功。
因为在很多场合下一些功能是选配的,我们可以实现定义好函数名字,并声明为弱符号,如果需要实现某个功能就去实现他的函数体。譬如一些钩子函数/回调函数就可以使用这种技巧来做。

猜你喜欢

转载自blog.csdn.net/qq_33894122/article/details/80851171
今日推荐