• 【C++深度剖析】为什么C++支持函数重载而C不支持--C++程序编译链接过程--符号表生成规则【Linux环境超详细解释C++函数重载底层原理】


    在这里插入图片描述

    前言

    先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记关注我哦!️️️

    这一篇的内容涉及C++程序运行底层,我们需要对C++程序的编译和链接过程要非常熟悉,我们才可以掌握这一篇的内容。在这里,博主先给大家安利一篇程序编译链接的干货文章。这里面的内容对大家的学习是非常有帮助的。

    由于这篇文章的内容我们需要用Linux环境来进行演示,因此我们先要熟悉Linux的一些基本操作。


    那么这里博主先安利一下一些干货满满的专栏啦!

    数据结构专栏:数据结构 这里包含了博主很多的数据结构学习上的总结,每一篇都是超级用心编写的,有兴趣的伙伴们都支持一下吧!
    算法专栏:算法 这里可以说是博主的刷题历程,里面总结了一些经典的力扣上的题目,和算法实现的总结,对考试和竞赛都是很有帮助的!
    力扣刷题专栏:Leetcode 想要冲击ACM、蓝桥杯或者大学生程序设计竞赛的伙伴,这里面都是博主的刷题记录,希望对你们有帮助!
    C的深度解剖专栏:C语言的深度解剖 想要深度学习C语言里面所蕴含的各种智慧,各种功能的底层实现的初学者们,相信这个专栏对你们会有帮助的!


    Linux环境g++编译器的配置以及一些准备工作

    如果要搞清楚C++支持重载的原因的本质,我们需要使用g++编译器来逐步编译源文件。

    • gcc是C的编译器
    • g++是C++的编译器

    在我们安装Linux环境的时候,gcc一般是已经帮我们安装好了的,但是g++需要我们自己配置一下,输入一个指令即可
    配置g++指令:yum install gcc-c++ libstdc++-devel
    当然,这个指令需要root权限,我们在指令前加个sudo,然后输入密码即可。
    在这里插入图片描述
    现在g++已经安装好了,使用方式和gcc大致相同,还没弄清楚的伙伴可以参考这篇,了解一下怎么逐步编译源文件。

    准备工作:
    准备三个源文件,func.h func.c test.c(不会弄的先看看博主关于Linux基本指令的文章,先学会在Linux环境下编程)
    .h文件里面准备好两个相互重载的函数的声明
    func.c文件里面准备好这两个函数的定义
    test.c里面准备好函数的调用代码

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述


    注意:为什么我们写C++程序,后缀可以用.c,这是因为在Linux系统中,后缀其实不那么重要,辨识文件的其实是iNode,这个博主在往期博客里有讲,在文章开头有传送门。
    无论我写成.c还是.cpp,只要我用gcc编译就是C语言,用g++编译就是C++。


    源文件的符号表生成以及分析

    在这里博主带大家复习一下,一个源文件到一个可执行程序(windows下为.exe,linux下为.out)的过程。
    在这里插入图片描述
    在这里插入图片描述


    那么为什么C++可以支持函数重载呢?其实就是在汇编过程生成符号表的时候,函数名修饰规则支持的!
    现在,我们先把符号表找出来看看!我们看看func.c的符号表,这里涉及很多Linux的操作,博主还是继续提供传送门。

    我们输入指令g++ test.c -cg++ func.c -c来生成test.cfunc.c 所对应的汇编文件,test.ofunc.o(用gcc编译会报错,因为C不支持重载)
    在这里插入图片描述
    我们用readelf这个工具查看.o文件的符号表。
    -s选项选择查看符号表。(这些博主在传送门的文章里都有讲)
    在这里插入图片描述
    此时我们可以清晰的发现,两个名字相同的函数经过修饰之后,名字不同了。
    _Z4funcid
    _Z4funcii
    其中4代表函数名的长度,id代表参数类型的首字母(ii同理)

    这就是为什么在链接的时候不会有名字冲突的情况出现。
    因为g++编译器也就是C++的编译器,在形成符号表的时候会对函数名进行修饰,而且修饰过后的名字和函数的参数有关!


    现在我们换gcc(C的编译器)来尝试一下,看看符号表的函数名,还有没有这种修饰,当然,在此之前我们要调整一下源文件里面的内容,把重载函数去掉,否则会报错。
    在这里插入图片描述
    在这里插入图片描述


    看到这里,相信大家已经可以清楚的了解到:C++支持函数重载的本质原因,其实就是生成符号表时的函数名修饰规则


    尾声

    看到这里,我相信伙伴们对这个问题已经有了比较深入的了解了。
    如果这篇博客对你有帮助,一定不要忘了点赞关注和收藏哦!

  • 相关阅读:
    Redis性能滑坡:哈希表碰撞的不速之客【redis第二部分】
    Feign 从注册到调用原理分析
    rasa 对话机器人--http rest api
    CentOS7安装Oracle-19c
    小工具使用——瑞士军刀(nc.exe)实现远程控制终端操作
    大家常说的表空间到底是什么?究竟什么又是数据表呢?
    2022-2023年度的AMC数学竞赛报名时间来了
    230. 二叉搜索树中第K小的元素 java解决
    arx 实体标准
    JavaScript面试题6
  • 原文地址:https://blog.csdn.net/Yu_Cblog/article/details/125883096