码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 多重定义的全局符号,链接器会如何链接的情况


    多重定义的全局符号,链接器会如何链接的情况

    • 实例1:
      • 1.规则1
      • 2.规则1
      • 3.规则2
      • 4.规则3
    • 实例2
    • 总结

    以下只针对于gcc编译器,而且不同环境,不同编译器的情况可能不同。

    假如说有多重定义的全局符号,链接器会如何链接呐?

    在编译时,编译器向汇编器输出每个全局符号,根据它是强符号还是弱符号,把这个信息隐含地编码在可重定位目标文件的符号表李。

    强符号:函数和已初始化的全局变量
    弱符号:未初始化的全局变量。

    根据强弱符号定义,Linux链接器使用下的规则来处理多重定义的符号名。

    1.不允许有多个同名的强符号。

    2.如果有一个强符号和多个弱符号同名,那么选择强符号。

    3.如果有多个弱符号同名,那么从这些弱符号中任意选择

    实例1:

    1.规则1

    a.c

    int main()
    {
         return 0;
    }
    
    • 1
    • 2
    • 3
    • 4

    b.c

    int main()
    {
         return 0;
    }
    
    • 1
    • 2
    • 3
    • 4

    编译结果:在这里插入图片描述

    2.规则1

    a.c

    int x=2;
    int main()
    {
        return 0; 
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    b.c

    int x =1;
    
    • 1

    在这里插入图片描述

    3.规则2

    a.c

    #include
    void f(void);
    int x =2;
    int main()
    {
        f();
        printf("%d",x);
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    b.c

    int x ;
    void f()
    {
         x=10;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    运行结果
    在这里插入图片描述

    4.规则3

    a.c

    #include
    int x;
    void fun(void);
    int main()
    {
        x =12;
        fun();
        printf("%d",x);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    b.c

    int x;
    void fun()
    {
        x=15;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    运行结果
    在这里插入图片描述

    规则2和规则3会造成一些不易察觉的运行时的错误,我们一定要注意。

    实例2

    a.c

    #include
    int x = 12;
    int y = 13;
    void fun(void);
    int main()
    {
        fun();
        printf("x= 0x%x y= 0x%x \n",x,y);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    b.c

    double x;
    void fun()
    {
         x =-0.0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    !!!此时b.c中的x=-0.0这一语句把a.c中 类型为int 的x和y都改了。

    总结

    当编译器在编译某个模块时,遇到一个弱全局符号,如x,它不知道其它模块是否也定义了该变量,如果定义了,它无法预测链接器使用哪一个x,所以编译器把x分配成COMMON,把决定权留给链接器,如果x被初始化0,那么它将是一个强符号,所以编译器直接将它成配成.bss。

    所以我们在定义全局变量时,一定要初始化,避免使它成为弱符号!!!。

  • 相关阅读:
    【案例30】WebSphere诡异宕机
    Python学习基础笔记七十七——json序列化
    Oracle 和 mysql 增加字段SQL
    数字IC基础:有符号数和无符号数的加减运算
    大数据-之LibrA数据库系统告警处理(ALM-12049 网络读吞吐率超过阈值)
    【解决】运行vue项目,启动报错 in ./node_modules/@intlify/core-base/dist/core-base.cjs
    通过无线自制串口模块连接SpeedyBee或BetaFlightConfigurator
    Vue电影网站构建实战教程
    记某信漏洞复现
    【JAVA UI】【HarmonyOS】 鸿蒙setBindStateChangedListener的基本使用
  • 原文地址:https://blog.csdn.net/aoeaoao/article/details/128064479
  • 最新文章
  • 沪漂五周年了:我越来越迷茫了
    Agentic Skill Routing 实战:别再把所有 Skill 塞进 AI Agent 上下文
    MySQL-Seconds_behind_master的精度误差
    [MAF预定义ChatClient中间件-03]CachingChatClient——利用缓存省钱省时间
    AI的至暗历史:从万众期待到被政府撤资,AI的两次死亡徘徊
    Agent OS :五种驯服不确定性的范式
    PortSwigger SQL注入LAB11
    数据库即时编译JIT
    [Begin]AI Learn Data Day 0
    深度学习进阶(二十七)现代 LLM 的核心架构设计其二:SwiGLU
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
小工具 小游戏
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1

京公网安备 11010502049817号