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

gcc/g++使用格式+各种选项,预处理/编译(分析树,编译优化,生成目标代码)/汇编/链接过程(函数库,动态链接)

目录

gcc/g++--编译器

介绍

使用格式

通用选项

编译选项

链接选项

程序编译过程

预处理(宏替换)

编译 (生成汇编)

分析树(parse tree)

编译优化

删除死代码

寄存器分配和调度

强度削弱

内联函数

生成目标代码 

汇编 (生成二进制代码)

链接(生成可执行文件) 

函数库

引入

介绍

动态链接

 示例​编辑


gcc/g++--编译器

介绍

是GNU编译器集合(GNU Compiler Collection)中的两个重要组件,用于编译和链接程序

使用格式

g++也一样

一般是:

通用选项

编译选项

eg:

链接选项

eg:

 

程序编译过程

预处理(宏替换)

预处理后,生成.i文件,可以通过-E选项拿到编译的中间过程中的.i文件

编译 (生成汇编)

  • 从.i文件中,编译器会对其进行词法/语法/语义分析,并且会对代码进行优化
  • 编译后生成.s文件,使用-S选项可以拿到这个.s文件
分析树(parse tree)
  • 是一种用于表示源代码语法结构的树状数据结构,通常通过语法分析器生成
  • 它反映了源代码中的各个语法元素(如关键字、运算符、变量、函数调用等)之间的嵌套关系,帮助编译器理解代码的结构并执行后续的编译步骤
  • 它将源代码分解为一个个语法单元,然后根据编程语言的语法规则将这些单元组合成树状结构

编译优化

为了提高计算机程序的执行效率和性能,会进行编译优化

删除死代码

实际不会产生作用的代码:

  • 执行不到的代码
  • 执行的到但是没有用的代码(没有使用过的变量))
寄存器分配和调度
  • 很多编译器会将 for循环的循环控制变量 调度到寄存器访问(寄存器快!)
强度削弱
  • 执行时间较短的操作(指令)去代替一个耗时操作
  • 下面的代码,由于需要使用的是计算的结果,因此中间数可以被替换掉(比如*变+):
#include <iostream> 
using namespace std; int main() 
{    int a1 = 5; int b1 = 17; int c1 = a1 * b1; cout << c1 << endl; // 强度削弱 int a2 = 5; int b2 = a2 << 4; int c2 = a2 + b2; cout << c2 << endl; return 0; 
} 
内联函数

除了编译器自动做出的优化,程序员在编写的时候也需要手动进行优化(因为编译器没有我们想的那么智能啦)

  • 内联函数(将 短小但常用的函数 定义为内联函数(inline),可以减少函数调用开销)

  • 但其实内联函数也可以被编译器自动识别并使用

生成目标代码 
  • 将经过语法分析和语义分析的源代码转化为目标代码,这个目标代码可以是汇编语言、中间代码或直接的机器代码,具体取决于编译器的设计和目标平台
  • 代码生成器的主要任务是将 [高级编程语言的源代码] 翻译成 [目标平台的可执行代码]

 

汇编 (生成二进制代码)

中间过程也有很多,就不介绍了

 

链接(生成可执行文件) 

函数库
引入
  • 我们在使用库函数时,是直接调用+引用头文件
  • 但是头文件中只有函数声明,那么实现在哪里呢?
介绍
  • 函数库分为静态库和动态库 
  • 使用静态库的方式就是静态链接,使用动态库的方式就是动态链接
  • 其中,静态库内存开销大,但不需要库文件,后缀.a
  • 动态库开销很小,一份库文件可以被多个程序共享使用,所以一般都会使用动态链接,后缀.so
动态链接
  • 当程序运行时,动态链接器会查找并加载所需的库,根据可执行文件中的引用信息,将库文件映射到进程的地址空间
  • 动态链接器解析程序中的未解析引用,将其与库中的实际函数或符号关联起来
  • 程序在运行过程中,会调用库中的函数或方法
  • 并且,库是在运行时加载的,因此库的更新可以在不停止程序的情况下进行

 示例
  • 直接编译生成的是那个test(也就是使用了gcc的动态链接)
  • test_static是在编译的时候,选择了使用静态库链接生成的
  • 可以看到大小差很多

 

总结来说,编译过程的选项是" esc ",只不过在实际使用时,只有c是小写字母,其他都是大写字母

http://www.lryc.cn/news/214265.html

相关文章:

  • OSPF复习(2)
  • FPGA时序分析与约束(9)——主时钟约束
  • sqlite3 关系型数据库语言 SQL 语言
  • spring boot中的多环境配置
  • python3 阿里云api进行巡检发送邮件
  • 【Linux】安装使用Nginx负载均衡,并且部署前端项目
  • k8s中 pod 或节点的资源利用率监控
  • 订水商城实战教程07-搜索
  • stm32内 misc stm32f10x_hd stm32f10x_it stm32f10x_conf关系
  • 树结构及其算法-二叉查找树
  • PHP自定义文件缓存实现
  • 猫耳 Android 播放框架开发实践
  • linux下df -h 命令一直卡住的解决方法
  • 系统架构设计热点知识
  • 2023-在mac下安装Homebrew的国内镜像
  • Ubuntu 20.04设置虚拟内存 (交换内存swap)解决内存不足
  • RabbitMQ-死信交换机和死信队列
  • [HNCTF 2022 WEEK2]easy_include 文件包含遇上nginx
  • python中transform和apply的区别是什么
  • TCP 协议
  • Azure机器学习 - 在 Azure 机器学习中上传、访问和浏览数据
  • 新建包含cuda和cudnn的docker
  • Opensips安装配置(以下操作均已centOS 6.3系统为准)
  • 第03章 用户与权限管理
  • 赋能制造业高质量发展,释放采购数字化新活力——企企通亮相武汉2023国际智能制造创新论坛
  • 洗地新天花板:CEYEE希亦顶配机皇T800 Pro洗地机多点发力上市开售
  • 如何创建一个react项目
  • 面试算法49:从根节点到叶节点的路径数字之和
  • http1,https,http2,http3总结
  • stable-diffusion-webui环境部署