C++编译底层

news2024/11/30 0:51:05

C/C++编译底层

  • C++内存管理
  • LINUX进程区分段及存储数据
  • GCC编译流程
  • 动态库静态库区别及LINUX加载库
  • extern C的结果和CPP编译的区别
  • 重载的底层原理
  • 编译性语言和解释性语言的本质区别和优缺点

C++内存管理

  • 存储函数的返回地址、参数、局部变量、返回值,从高地址向低地址增长
  • malloc/free开辟内存的空间,从低地址向高地址增长
  • 自由存储区 new/delete开辟内存空间
  • 数据区
    数据区包含全局/静态存储区和常量存储区,存储已初始化的全局变量和静态变量、未初始化的全局变量和静态变量及字符串常量
  • 代码区 存储程序的机器代码和程序指令

LINUX进程区分段及存储数据

Linux的每个进程都有各自独立的4G逻辑地址,其中0-3G是用户态空间,3~4G是内核空间,不同进程相同的逻辑地址会映射到不同的物理地址中。
逻辑地址分段如下,自下而上:

  • 代码段。分为只读存储区和代码区,存放字符串常量和程序机器代码和指令
  • 数据段。存储已初始化的全局变量和静态变量。
  • bss段。存储未初始化的全局变量和静态变量,及初始化为0的全局变量和静态变量
  • 堆。 当进程未调用malloc时是没有堆段的,malloc/free开辟的内存空间,向上生长
  • 映射区。存储动态链接库以及调用mmap函数进行的文件映射
  • 栈。存储函数的返回地址、参数、局部变量、返回值,向下生长。

GCC编译流程

  • 预处理阶段:hello.c – “gcc -E预处理,头文件展开,宏替换,删除注释、空白” --> hello.i
  • 编译阶段:hello.i – “gcc -s检查语法规范、生成汇编文件” --> hello.s
  • 汇编阶段:hello.s – “gcc -c生成二进制文件” --> hello.o
  • 链接阶段:hello.o – “数据段合并、地址回填,调用ld进行链接” --> a.out

动态库静态库区别及GCC加载库

静态库

  • 编译时期链接
  • 浪费空间和资源,如果多个程序链接了同一个库,则每一个生成的可执行文件就都会有一个库的副本,必然会浪费系统空间。
  • 若静态库需修改,需重新编译所有链接该库的程序

动态库

  • 运行时链接
  • 运行时被链接,故程序的运行速度稍慢
  • 动态库是在程序运行时被链接的,所以磁盘上只须保留一份副本,因此节约了磁盘空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉即可

GCC编译加载静态库

  • 将所有的.c文件编译成.o目标文件

    • gcc -c add.c 生成add.o
    • gcc -c max.c 生成max.o
  • 对生成的.o目标文件打包生成静态库

    • ar crv libfoo.a add.o max.o //libfoo.a是库的名字,其中lib一定要有
    • ar:做库的命令
    • c:创建库
    • r:将方法添加到库里
    • v:显示过程,可以不要
  • 使用静态库

    • gcc -o main main.c -static -L. -lfoo //这里写的foo是去掉前后缀后库的名字
    • -L:指定路径 .代表当前路径
    • -l:指定库名

GCC编译加载动态库

  • 对生成的.o文件处理生成共享库,共享库的名字为libfoo.so

    • gcc -shared -fPIC -o libfoo.so add.o max.o
    • -shared 表示输出结果是共享库类型的
    • -fPIC 表示使用地址无关代码(Position Independent Code)技术来生产输出文件
  • 库的使用

    • cp libfoo.so /usr/lib //将库拷贝到系统库路径下(不推荐)

    • export 更改 LD_LIBRARY_PATH 当前终端的环境变量

    • 修改/etc/ld.so.conf文件,加入库文件所在目录的路径,然后
      运行ldconfig 目录名字,该命令会重建/etc/ld.so.cache文件即可

    • 上面三种选一个即可gcc -o main main.c -lfoo

extern-C的结果和CPP编译的区别

  • 一个C语言文件p.c
#include <stdio.h>
void print(int a,int b)
{
       printf("这里调用的是C语言的函数:%d,%d\n",a,b);
}
  • 一个头文件p.h
#ifndef _P_H
#define _P_H

void print(int a,int b);

#endif
  • C++文件调用C函数
#include <iostream>
using namespace std;
#include "p.h"
int main()
{
       cout<<"现在调用C语言函数\n";
       print(3,4);
       return 0;
}
  • 编译后链接出错:main.cpp对print(int, int)未定义的引用。

  • 原因分析

    • p.c我们使用的是C语言的编译器gcc进行编译的,其中的函数print编译之后,在符号表中的名字为 _print
    • 我们链接的时候采用的是g++进行链接,也就是C++链接方式,程序在运行到调用print函数的代码时,会在符号表中寻找 _print_int_int(是按照C++的链接方法来寻找的,所以是找 _print_int_int而不是找_print)的名字,发现找不到,所以会t提示“未定义的引用”
    • 此时如果我们在对print的声明中加入 extern “C” ,这个时候,g++编译器就会按照C语言的链接方式进行寻找,也就是在符号表中寻找_print,这个时候是可以找到的,是不会报错的。
  • 总结

    • 编译后底层解析的符号不同,C语言是_print,C++是_print_int_int

重载的底层原理

根据上面的编译分析,可以知道C语言没有重载,只有C++才有函数重载,因为函数重载通过参数列表的不同来实现。

  • C语言没有重载
"int __cdecl Add(int,int)" (?Add@@YAHHH@Z)
"double __cdecl Add(double,double)" (?Add@@YANNN@Z)
"long __cdecl Add(long,long)" (?Add@@YAJJJ@Z)

在C语言中被解析为_Add,三个一样,所以不能进行区分,因此C语言不支持函数重载

  • C++重载
    底层的重命名机制将Add函数根据参数的个数,参数的类型,返回值的类型都做了重新命名。那么借助函数重载,一个函数就有多种命名机制。 _Add_int_int,_Add_long_long,_Add_double_double

  • C++中可以通过在函数声明前加 extern “C” 将一个函数按照 C 语言的风格来进行编译。

编译性语言和解释性语言的本质区别和优缺点

  • 根本区别

    • 计算机不能直接的理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言的编写的程序。翻译的方式有两种,一个是编译,一个是解释。两种方式只是翻译的时间不同
    • 解释性语言不用编译,在运行时翻译
    • 编译性语言是编译的时候直接编译成机器可以执行的语言,编译和运行是分开的,但是不能跨平台。比如exe文件,以后要运行的话就不用重新编译了,直接使用编译的结果就行了(exe文件),因为翻译只做了一次,运行的时不要翻译,所以编译型语言的程序执行效率高
  • 编译性语言的优缺点

    • 优点
      • 运行速度快,代码效率高,编译后程序不可以修改,保密性好
    • 缺点
      • 代码需要经过编译方可运行,可移植性差,只能在兼容的操作系统上运行。
  • 解释性语言的优缺点

    • 优点
      • 可移植性好,只要有解释环境,可以在不同的操作系统上运行。
    • 缺点
      • 运行需要解释环境,运行起来比编译的要慢,占用的资源也要多一些,代码效率低,代码修改后就可以运行,不需要编译过程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/991797.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux ifconfig只显示 lo 网卡,没有ens网卡解决方案

项目场景&#xff1a; 虚拟机中linux无网络问题 问题描述 之前在调试linux的时候&#xff0c;由于一些不太清楚的误操作&#xff0c;导致ubuntu linux出现无网络问题&#xff0c;现象如下 ifconfig 只显示了 lo 网卡 lo 网卡&#xff1a;它是本地环回接口。 这意味着您的虚…

Ubuntu系统下安装常用软件

安装MySQL 1、卸载清理残余 dpkg --list|grep mysqlsudo apt-get remove mysql-common2、升级apt sudo apt-get update3、安装MySQL sudo apt-get install mysql-server4、启动和关闭mysql的命令如下 #启动: sudo service mysql start#重启: sudo service mysql restart #…

Linux之查看so/bin依赖(三十一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

亿发多门店商品管理信息化解决方案,可以帮助企业解决那些问题

在现代商业世界中&#xff0c;高效的管理是企业成功的关键之一。而进销存系统作为企业信息化管理的重要组成部分&#xff0c;对于加强企业的运营效率和竞争力具有至关重要的作用。许多企业正寻求专业的商品管理信息化 解决方案,支持其业务运营。亿发进销存管理系统,一个平台统一…

如何制作一个卡刷扩容补丁。用于扩容系统等分区 刷写第三方需要扩容才可以刷写的系统或者GSI GSI系统bug修复【二】

前面分享了一期手动扩容系统分区的博文&#xff0c;今天来系统解析下扩容卡刷补丁的制作。因为机型字库不同。挂载的分区方式也有所不同。操作前首先确定自己机型的字库芯片。以一款emmc芯片的扩容补丁为例来解析其操作原理&#xff1a; 安卓系列机型--软扩容“system分区扩容…

003微信小程序云开发API数据库-新增集合-删除集合-获取集合信息

文章目录 1.微信小程序云开发API数据库-新增集合案例代码 2.微信小程序云开发API数据库-删除集合案例代码 3.微信小程序云开发API数据库-获取集合信息案例代码 1.微信小程序云开发API数据库-新增集合 微信小程序云开发API数据库是一个方便快捷的数据库解决方案&#xff0c;可以…

快捷支付是什么?怎么申请支付接口?

快捷支付是什么&#xff1f;怎么申请支付接口&#xff1f; 快捷支付&#xff0c;又称电子支付或第三方支付&#xff0c;在行业中得到了广泛的应用。用户只需通过银行完成交易。方便快捷意味着银行可以在任何条件下支持用户之间的转账、支付和其他即时结算服务。快捷支付意味着…

阿里云APP备案操作流程_新手看过来

阿里云APP备案流程分为6步&#xff0c;APP备案成功后应用可以上架&#xff0c;登录阿里云账号填写APP信息&#xff0c;等待阿里云初审&#xff0c;初审通过后进行工信部短信核验&#xff0c;管局审核通过后APP即可备案成功&#xff0c;最后移动APP应用可以分发平台上架&#xf…

Linux中select poll和epoll的区别

在Linux Socket服务器短编程时&#xff0c;为了处理大量客户的连接请求&#xff0c;需要使用非阻塞I/O和复用&#xff0c;select、poll和epoll是Linux API提供的I/O复用方式&#xff0c;自从Linux 2.6中加入了epoll之后&#xff0c;在高性能服务器领域得到广泛的应用&#xff0…

Fastchat:基于fastapi构建大模型加载服务

Fastchat&#xff1a;基于fastapi构建大模型加载服务 Fastapi LLM支持FastChat 服务架构安装方法一&#xff1a;pip方法二&#xff1a;源文件 加载大模型推理1.命令行2.Web启动控制器启动模型工作启动 Gradio Web 服务器注册多个模型 3.兼容 OpenAI 的 RESTful API RESTful API…

CSS 滚动驱动动画 view()

CSS 滚动驱动动画 view 语法例子 两个 inset一个 inset CSS 滚动驱动动画 view() animation-timeline 通过 view() 表示一个元素 A 将提供匿名的、 用来控制动画的 view progressive timeline. 通过 A 在其最近的滚动祖先元素中的可见性来推动 view progressive timeline. 也…

PHP自己的框架2.0版本目录结构和命名空间自动加载类(重构篇一)

目录 1、目录结构演示效果 2、搭建目录结构&#xff0c;以及入口public->index.php 3、引入core下面core->base.php 4、自动加载实现core->fm->autoload.php 5、框架运行文件core->fm->core.php 6、最终运行index.php结果 1、目录结构演示效果 2、搭…

单目标应用:基于成长优化算法(Growth Optimizer,GO)的微电网优化调度MATLAB

一、微网系统运行优化模型 微电网是由分布式电源、储能装置和能量转换装置等组成的小型发配电系统&#xff0c;具有成本低、电压低、污染小等特点。由于环保和能源压力&#xff0c;清洁可再生能源和分布式能源工业发展潜力巨大。微电网控制器可实现对电网的集中控制&#xff0…

【C++笔记】C++string类模拟实现

【C笔记】Cstring类模拟实现 一、实现模型和基本接口1.1、各种构造和析构1.2、迭代器 二、各种插入和删除接口2.1、插入接口2.2、删除接口2.3、resize接口 三、各种运算符重载3.1、方括号运算符重载3.2、各种比较运算符重载 四、查找接口4.1、查找字符4.2、查找子串 五、流插入…

【7z密码】如何给7z压缩包加密、解密?

7z压缩包是压缩率最大的格式&#xff0c;也有很多朋友会使用7z格式&#xff0c;那么7z压缩包如何进行加密、解密&#xff1f;今天给大家介绍详细教程。 7-zip加密 右键文件选择7-zip打开压缩软件进行压缩或者在打开7-zip软件找到需要压缩的文件&#xff0c;点击添加&#xff…

【大数据】基于 Flink CDC 高效构建入湖通道

基于 Flink CDC 高效构建入湖通道 1.Flink CDC 核心技术解析2.CDC 数据入湖入仓的挑战2.1 CDC 数据入湖架构2.2 CDC 数据 ETL 架构 3.基于 Flink CDC 的入湖入仓方案3.1 Flink CDC 入湖入仓架构3.2 Flink CDC ETL 分析3.3 存储友好的写入设计3.4 Flink CDC 实现异构数据源集成3…

ECharts数据可视化项目

Echarts 可视化面板介绍01-使用技术02- 案例适配方案03-基础设置04-header 布局05-mainbox 主体模块06-公共面板模块 panel07-柱形图 bar 模块(布局)08-中间布局09-Echarts-介绍10-Echarts-体验11-Echarts-基础配置12- 柱状图图表&#xff08;两大步骤&#xff09;13-柱状图2定…

基于Java+SpringBoot+Vue前后端分离交通管理在线服务系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

地形有通挂支隘险远六种情况

地形有通、挂、支、隘、险、远六种情况 【安志强趣讲《孙子兵法》第34讲】 第十一篇&#xff1a;地形篇 【全文大白话】 地形有各种情况&#xff0c;行军有各种情况&#xff0c;用好地形获得交战的主动权。 【原文】 孙子曰&#xff1a;地形有通者&#xff0c;有挂者&#xff0…

百家号创业项目:小白即可日入30到100,寻找爆款文案技术教程免费分享

百家号项目&#xff1a;月入1K-3K不费力&#xff0c;寻找爆款文案的秘诀&#xff01; 当下&#xff0c;有一个备受关注的项目——百家号&#xff0c;许多人以 300-800 元不等的价格提供培训&#xff0c;声称每个号每月可以轻松赚取1K-3K。 然而&#xff0c;据我个人测试&…