C的强符号/弱符号

首先上代码和结果:

代码:

#include  <stdio.h>
int k;
int k;
int main()
{
    printf("addr of k = %p\n", &k);
    printf("value of k = %d\n", k);
    return 0;
}

结果:

addr of k  = 00408074
value of k = 0

问题:
由结果可得,系统已为全局变量k开辟了内存空间(因为可以打印到变量k的地址),并且为该变量拥有初值0

可知,int k;为定义了全局变量k,但是为什么k能被定义两次呢?

分析:

  • 符号

在分析前,先来说明一下符号这个概念。在c程序生成可执行文件前,有以下步骤:预编译 -> 编译 -> 汇编 -> 链接

在生成.exe文件前的最后一步,即在链接步骤中,由项目中各个.c文件生成的.o文件(目标文件)会基于其符号表中的符号,来将各个.o文件链接在一起,生成可执行文件

下面用指令查看一下.o文件中的符号表

/* sym.c */
#include <stdio.h>
int sym = 1024;
int func_sym()
{
    return 0;
}

int main()
{
    return 0;
}

指令:

gcc sym.c -o sym.o // 生成sym.o文件
nm sym.o // 查看.o文件的符号表

符号表部分内容如下:

…(省略)
00401a40 T ___main
00404004 D _sym
00401410 T _func_sym

可以看到符号表有变量sym,函数main和函数func_sym的符号

  • 强/弱符号

对于C/C++语言来说,编译器默认函数和初始化了的全局变量为强符号,未初始化的全局变量为弱符号。当然也可以通过
__attribute__((weak))
来定义一个强符号为弱符号。

通过下面的例子来看看哪些是强符号,哪些是弱符号

#include<stdio.h> 
int weak; // 定义但未初始化全局变量,弱符号 
int strong = 1024; // 定义且已初始化全局变量,强符号 
__attribute__((weak)) int weak1 = 2222; // 使用标识修饰的弱符号 
int main(void) 
{ 
    printf("test\n"); 
    return 0; 
} 

注意,这里的强符号与弱符号都是针对定义来说的。

原理:

同名时,用哪个?变量重名时,链接器有它的处理方式:

  1. 强符号不允许重复
  2. 有一个强符号和多个弱符号,使用强符号
  3. 多个弱符号,则随意选择一个

由3.可知,在

#include  <stdio.h>
int k;
int k;
int main()
{
    printf("addr of k = %p\n", &k);
    printf("value of k = %d\n", k);
    return 0;
}

中,第一个k和第二个k均为未初始化的全局变量,所以均为弱符号;所以随意选择一个

参考:

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值