当前位置: 首页 > news >正文

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均为未初始化的全局变量,所以均为弱符号;所以随意选择一个

参考:

  • 函数或全局变量重复定义时会怎样?
  • C语言中的强符号与弱符号
http://www.lryc.cn/news/42794.html

相关文章:

  • AD/DA转换(XPT2046)
  • 乐观锁和悲观锁 面试题
  • 【Autoware规控】mpc_follower模型预测控制节点
  • 成果VR虚拟3D展厅让内容更丰富饱满
  • 【CE进阶】lua脚本使用
  • 【vue2】近期bug收集与整理02
  • 2. 01背包问题
  • 【Docker】CAdvisor+InfluxDB+Granfana容器监控
  • k8s 部署nginx 实现集群统一配置,自动更新nginx.conf配置文件 总结
  • 动态内存管理(上)——“C”
  • GPT-4发布,这类人才告急,大厂月薪10W+疯抢
  • MySQL数据库实现主主同步
  • JavaScript传参的6种方式
  • 蓝桥之统计子矩阵
  • Java的基础面试题
  • J1939故障码诊断说明
  • XCPC第十三站,贪心问题
  • 一文让你吃透 Vue3中的组件间通讯 【一篇通】
  • EVE遭遇大规模DDOS攻击,玩家和官方都傻眼了
  • 【数据结构】二叉树及相关习题详解
  • 锂电池充电的同时也能放电吗?
  • 通信工程考研英语复试专有名词翻译
  • 注意力机制(四):多头注意力
  • 【2023Unity游戏开发教程】零基础带你从小白到超神19——射线检测
  • 内存泄漏和内存溢出的区别
  • 文本三剑客之sed编辑器
  • 深度学习:GPT1、GPT2、GPT-3
  • 使用Docker 一键部署SpringBoot和SpringCloud项目
  • 【数据结构】用栈实现队列
  • [Netty源码] 服务端启动过程 (二)