c/c++ 程序运行的过程分析

news2024/11/27 8:30:03

c/c++编译基础知识

GNU

GNU(GNU’s Not Unix!)是一个由理查德·斯托曼(Richard
Stallman)在1983年发起的自由软件项目,旨在创建一个完全自由的操作系统,包括操作系统的内核、编译器、工具、库、文本编辑器、邮件系统、新闻系统等。GNU项目是自由软件运动的核心,其目标是确保用户有使用、复制、修改和分发软件的自由。

GNU项目的一些关键组件包括:

  1. GCC(GNU Compiler Collection):一套支持多种编程语言的编译器,包括C、C++、Objective-C、Fortran、Ada、Go等。

  2. GDB(GNU Debugger):一个强大的程序调试工具,用于调试C和C++程序。

  3. Glibc(GNU C Library):GNU项目开发的C标准库实现,广泛用于Linux操作系统。

  4. Gawk:一个文本处理工具,类似于Unix的awk。

  5. Grep:一个用于搜索文本的工具,类似于Unix的grep。

  6. Gnuplot:一个绘图工具,用于绘制函数、数据等图形。

  7. Emacs:一个功能强大的文本编辑器。

  8. Bash(Bourne Again Shell):一种Unix shell和命令语言。

  9. GnuPG(GNU Privacy Guard):一个加密软件,用于数据加密和数字签名。

  10. AutoconfAutomake:用于生成配置脚本和Makefile的工具。

GNU项目还开发了Hurd,这是一个旨在替代Unix内核的操作系统内核,但由于种种原因,Hurd并没有得到广泛的应用。相反,Linux内核(由林纳斯·托瓦兹开发)与GNU工具集合成为今天广泛使用的Linux操作系统。

GNU项目强调软件的自由性,其发布的软件遵循GNU通用公共许可证(GPL),这是一种“传染性”的许可证,要求所有基于GPL软件的衍生作品也必须以GPL发布,从而确保软件的自由性得以传递。

GCC

GCC,全称为GNU编译器集合(GNU Compiler
Collection),是一个由GNU项目开发的编程语言编译器系统。它支持多种编程语言,包括但不限于C、C++、Objective-C、Fortran、Ada、Go和D等。GCC是自由软件,遵循GNU通用公共许可证(GPL)发布。

GCC的主要特点包括:

  1. 跨平台:GCC可以在多种操作系统上编译源代码,包括Linux、Windows、macOS等。

  2. 优化:GCC提供了多种优化选项,以提高生成代码的执行效率。

  3. 调试支持:GCC能够生成调试信息,与GDB(GNU Debugger)等调试工具配合使用。

  4. 多种语言支持:GCC支持多种编程语言的编译,使其成为一个多功能的编译器集合。

  5. 自动并行化:GCC的一些版本提供了自动并行化的功能,可以自动将某些循环转换为并行执行的形式。

  6. 内联汇编:GCC支持内联汇编语言,允许开发者在高级语言代码中嵌入汇编指令。

  7. 插件支持:GCC允许通过插件扩展其功能。

  8. 交叉编译:GCC支持交叉编译,即在一种平台上编译出另一种平台上运行的代码。

GCC是许多Linux发行版默认的系统编译器,并且广泛用于嵌入式系统、高性能计算和各种软件开发项目中。由于其强大的功能和灵活性,GCC是开源社区中最受欢迎的编译器之一。

gcc 和 g++

GCC(GNU Compiler Collection)是一个编译器集合,它包括多个不同的编译器,其中最常用的是针对C语言的gcc和针对C++语言的g++。以下是gccg++的简要说明:

  1. gcc

    • 这是GNU项目提供的C语言编译器。
    • 它用于编译C语言源代码文件(通常以.c为扩展名)。
    • gcc支持多种操作系统和硬件平台,可以生成针对不同目标的可执行文件或库文件。
  2. g++

    • g++是GNU编译器集合中的C++语言编译器。
    • 它用于编译C++语言源代码文件(通常以.cpp.cc为扩展名)。
    • g++同样支持跨平台编译,并提供了C++特有的特性支持,如类、模板、异常处理等。

两者的主要区别在于它们支持的语言特性和标准库。gcc专门用于C语言,而g++则用于C++语言。尽管它们在某些底层组件上共享代码,但它们的前端(解析源代码的部分)是不同的,以适应各自语言的语法和特性。

使用示例:

  • 编译C语言程序: sh gcc -o program program.c 这将编译program.c并生成名为program的可执行文件。

  • 编译C++语言程序: sh g++ -o program program.cpp 这将编译program.cpp并生成名为program的可执行文件。

在实际使用中,您可能还会使用到其他选项和参数,例如优化标志(-O2)、调试信息生成(-g)、链接特定库(-L-l)等。此外,g++在编译混合C和C++代码时,也可以调用gcc来编译C语言部分的代码。

gcc 和 g++常见编译选项

gccg++提供了一系列的编译命令选项,用于控制编译过程的不同方面。以下是一些常用的编译命令选项:

  1. 输出可执行文件的名称sh -o <file> 指定输出的可执行文件名。

  2. 优化选项

    • -O0:没有优化。
    • -O1:启用基本优化。
    • -O2:进一步优化。
    • -O3:更多的优化,可能包括更激进的优化策略。
    • -Os:优化生成更小的代码。
  3. 调试信息sh -g 生成调试信息。

  4. 包括搜索路径sh -I <dir> 添加头文件搜索路径。

  5. 库搜索路径sh -L <dir> -l <library> 指定库文件的搜索路径,并链接指定的库。

  6. 链接时的库sh -l <library> 链接时包括特定的库。

  7. 静态链接sh -static 使用静态链接而不是动态链接。

  8. C++ 特定选项(在使用g++时): sh -std=c++11 -std=c++14 -std=c++17 -std=c++20 指定C++语言标准。

  9. 警告选项

    • -Wall:打开几乎所有的警告信息。
    • -Wextra:打开额外的警告信息。
    • -Werror:将所有警告当作错误处理。
  10. 编译特定文件

    -c
    

    只编译和生成目标文件(.o文件),不进行链接。

  11. 生成依赖文件

    -MF <depfile>
    

    生成包含依赖关系的文件。

  12. 使用多个处理器编译

    -j <n>
    

    使用n个处理器进行编译,可以加快编译速度。

  13. 指定架构

    -m32
    -m64
    

    指定生成32位或64位代码。

  14. 禁用标准库

    -nostdlib
    

    编译时不使用标准库。

  15. 内联汇编

    -S
    

    编译后只生成汇编代码。

这些只是gccg++提供的众多选项中的一部分。根据项目的具体需求,您可能还会使用到其他一些选项。在命令行中使用gcc --helpg++ --help可以查看完整的选项列表和说明。

c++ 程序运行的过程分析

  1. 编写完的 c/c++程序想要运行起来,需要四个步骤:预处理、编译、汇编、链接。
    在这里插入图片描述
  2. 编写 c++程序:main.cpp
#include <iostream>
using namespace std;

int add (int a, int b)
{
    return a+b;
}

int main()
{
    int x = 30;
    int y = 100;

    int ret = add(x, y);

    cout << "sum: " << ret << endl;

    return 0;
}

预处理

在C++编译过程中,预处理是一个重要的步骤,它发生在实际编译之前。以下是预处理的一些主要作用:

  1. 宏替换: 预处理器会处理宏定义(由#define指令定义)和宏展开。例如,如果你在代码中使用了#define PI 3.14159,预处理器会将代码中所有的PI替换为3.14159

  2. 文件包含: 使用#include指令包含标准库头文件或用户自定义的头文件。预处理器会将这些文件的内容插入到该指令的位置。

  3. 条件编译: 预处理器根据条件编译指令(如#ifdef#ifndef#if#else#elif#endif)来决定是否包含特定的代码段。这允许开发者根据不同的编译条件编写不同的代码。

  4. 行控制#line指令可以用来控制编译器报告错误和警告时显示的文件名和行号。

  5. 错误诊断: 使用#error指令可以在编译时生成错误信息。

  6. 编译时间计算#if指令可以用来进行编译时常量的计算和比较。

  7. 版本控制和编译选项: 预处理器可以根据不同的定义来启用或禁用特定的代码段,这通常用于处理不同操作系统或编译器的特性。

  8. 依赖性分析: 预处理器可以生成依赖性信息,这对于自动构建系统来说是有用的,以确保在头文件更改时重新编译依赖的文件。

  9. 函数宏和宏函数: 预处理器处理函数宏和宏函数的调用和展开。

  10. 预定义宏
    编译器会定义一些预定义宏,如__FILE____LINE____DATE____TIME__等,它们在预处理时被替换为当前文件名、行号、日期和时间。

预处理的结果是一个或多个预处理过的源文件,这些文件随后将被编译器进行语法分析、语义分析和代码生成等后续编译步骤。预处理是C++源代码转换为可执行程序的第一步,对于编译器正确理解源代码结构至关重要。

  1. 预处理命令g++ -E main.cpp -o main.i
  2. 生成文件main.i,仍是文本文件,可以用任意文本编辑器打开。

编译

编译是将高级语言代码转换成低级代码(通常是汇编代码或中间代码)的过程,侧重于语言特性的处理和代码优化。 编译阶段的作用:

  • 语法分析:检查代码是否符合C++语言的语法规则。
  • 词法分析:将源代码分解成一系列的词素(tokens)。
  • 语义分析:确保代码符合C++的语义规则,比如类型检查和作用域解析。
  • 抽象语法树(AST)构建:将源代码转换成AST,这是一种树状结构,表示程序的逻辑。
  • 优化:对AST进行优化,以提高程序性能或减少资源消耗。
  • 代码生成:将优化后的AST转换成中间代码或汇编代码。

在一些编译器实现中,编译阶段可能直接生成机器代码,而在其他情况下,编译器可能先生成汇编代码,然后由汇编器转换成机器代码。无论哪种情况,编译和汇编都是将源代码转换成可执行程序的必要步骤。

  1. 编译命令g++ -S main.cpp -o main.s
  2. 生成文件main.s

汇编

汇编是将汇编语言代码转换成机器代码的过程,侧重于目标机器的指令集和内存管理。 汇编阶段的作用:

  • 转换为汇编语言:将编译器生成的中间代码转换成目标机器的汇编语言。
  • 符号替换:将代码中的符号(如变量名和常量)替换为内存地址或立即数。
  • 地址分配:为代码和数据分配具体的内存地址。
  • 生成汇编文件:创建包含汇编指令的文件,这些指令可以被汇编器进一步处理。
  • 错误检测:检测汇编代码中的错误,如非法指令或不正确的地址引用。
  • 准备链接:生成的目标文件通常是可重定位的,为后续的链接阶段做准备。
  1. 汇编命令g++ -c main.cpp -o main.o 或者直接用汇编文件命令as main.s -o main.o
  2. 生成文件main.o

链接

C++编译的链接阶段是将编译器生成的目标文件(通常是.o.obj文件)组合成最终可执行文件或库文件的过程。以下是链接阶段的主要作用:

  1. 符号解析: 链接器解析目标文件中的符号引用,确保每个外部符号(变量和函数)都能正确地关联到其定义。

  2. 地址和空间分配: 链接器为程序中的代码和数据分配最终的内存地址,并决定它们在可执行文件中的布局。

  3. 代码和数据合并: 链接器将所有目标文件中的代码和数据合并成一个单一的可执行文件或库文件。

  4. 库链接: 如果程序依赖于外部库,链接器会将这些库中的代码和数据与目标文件合并。这包括静态库和动态库的链接。

  5. 重定位: 链接器处理重定位项,将代码和数据中的相对地址转换为绝对地址。

  6. 生成可执行文件: 对于最终的可执行文件,链接器生成一个可在操作系统上运行的程序。

  7. 生成库文件: 对于库文件,链接器生成一个包含多个函数和变量定义的文件,这些可以在其他程序中使用。

  8. 符号表生成: 链接器生成一个符号表,列出了程序中所有的符号及其地址。

  9. 调试信息整合: 如果编译时带有调试信息,链接器会整合这些信息到最终的可执行文件或库中。

  10. 资源文件处理
    链接器处理程序中使用的资源文件,如图形、声音等,并将它们整合到最终的程序中。

  11. 优化
    某些链接器或与之集成的工具可能会进行进一步的优化,如死代码消除。

  12. 生成调试符号
    如果需要,链接器可以生成调试符号文件,如DWARF格式的符号信息,以支持后续的调试工作。

  13. 错误检测
    链接器在链接过程中会检测未解决的外部引用或其他链接错误,并报告这些问题。

链接是编译过程的最后阶段,确保了所有编译后生成的片段能够正确地组合在一起,形成一个完整的程序。链接后的程序可以直接在目标机器上运行或被其他程序作为依赖库使用。

  1. 链接命令g++ -o main main.o
  2. 生成文件main

验证

  1. 文件目录
.
├── main
├── main.cpp
├── main.i
├── main.o
└── main.s
  1. 验证可执行程序./main
  2. 输出结果sum:130
admin@bogon test % ls
main		main.cpp	main.i		main.o		main.s
admin@bogon test % ./main
sum: 130

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

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

相关文章

渲染农场渲染真的很贵吗?如何正确使用云渲染农场?

作为渲染行业主流的技术服务“渲染农场"&#xff0c;一直都是备受大家关注&#xff0c;渲染农场最核心的在于充足的计算机算力&#xff0c;结合3D软件支持多台机器渲染的特点&#xff0c;租用渲染农场的机器帮助你快速的解决你的渲染项目。 虽然说渲染农场需要支付一定的…

Astro新前端框架首次体验

Astro新前端框架首次体验 1、什么是Astro Astro是一个静态网站生成器的前端框架&#xff0c;它提供了一种新的开发方式和更好的性能体验&#xff0c;帮助开发者更快速地构建现代化的网站和应用程序。 简单来说就是&#xff1a;Astro这个是一个网站生成器&#xff0c;可以直接…

MinIO:开源对象存储解决方案的领先者

MinIO:开源对象存储解决方案的领先者 MinIO 是一款开源的对象存储系统&#xff0c;致力于提供高性能、可伸缩、安全的数据存储解决方案。 官方解释&#xff1a;MinIO 是一个基于Apache License v2。0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适…

因版本冲突导致logback的debug日志不打印

因框架调整&#xff0c;降级了logback的版本号&#xff0c;由1.3.12降级为1.2.11&#xff08;因框架限制&#xff0c;只能采用1.2版本&#xff09;&#xff0c;降级后发现debug日志无法打印出来&#xff0c;logback.xml配置文件不生效。后排查发现是与slf4j的版本兼容问题 依赖…

以某头部基金实践为例,验证深信服超融合对TA系统承载能力

TA&#xff08;Transfer Agent&#xff09;开放式基金登记过户系统是交易管理系统的重要组成部分&#xff0c;是登记注册机构向投资者提供账户管理、份额登记、交易清算、红利发放、持有人名册保管的综合服务系统。 作为开放式基金运作的核心系统之一&#xff0c;承担着投资者…

Qt 加载图片的几种方式 以及加载 loading

项目中经常使用加载图片&#xff1a; 常用有两种方式&#xff1a; 1.使用 QWidget 加载图片&#xff1a; 效果&#xff1a; 样例源码&#xff1a; int pict_H ui->widgetImage->height();int pict_W ui->widgetImage->width();ui->widgetImage->setFixe…

【车载开发系列】GIT安装详细教程

【车载开发系列】GIT安装详细教程 【车载开发系列】GIT安装详细教程 【车载开发系列】GIT安装详细教程一. GIT软件概念二. GIT安装步骤三. GIT安装确认三. GIT功能使用1&#xff09;Git Bash2&#xff09;Git CMD3&#xff09;Git FAQs4&#xff09;Git GUI 一. GIT软件概念 G…

comsol随机材料参数赋值

comsol随机材料参数赋值 在comsol中定义外部matlab函数 在comsol中定义外部matlab函数 首选项&#xff0c;安全性&#xff0c;允许 材料中&#xff0c;将杨氏模量更改为变量函数 计算 应力有波动&#xff0c;可见赋值成功 也可以看到赋值的材料参数&#xff1a;

针对 LLM 应用程序优化 RAG

前言 大型语言模型 (LLM)&#xff08;如 GPT-4&#xff09;在生成类似人类的文本方面表现出了令人印象深刻的能力。然而&#xff0c;在保留事实知识方面&#xff0c;它们仍然面临挑战。这就是检索增强生成 (RAG) 的作用所在——将 LLM 的生成能力与外部知识源相结合。RAG 已成…

TAPD项目管理软件无法与企业微信进行关联

TAPD一段时间未使用后&#xff0c;需要重新启动&#xff0c;此时会出现你的企业微信尚未与TAPD账号关联的提示 解决方案&#xff1a;找到TAPD应用&#xff0c;先删除应用&#xff0c;然后再解除禁用即可

【anaconda】—“conda info“命令后conda配置和环境信息的理解

文章目录 conda配置和环境信息的理解 conda配置和环境信息的理解 安装anaconda成功后&#xff0c;打开cmd&#xff0c;输入"conda info"命令&#xff0c;结果显示如下&#xff1a; conda的配置和环境信息的输出。以下是对每个字段的解释&#xff1a; active environm…

【MySQL】详解

SQL语句的分类&#xff1a; 1.DDL&#xff08;Data Definition Languages&#xff09;语句&#xff1a; 数据定义语言 &#xff0c;这些语句定义了不同的数据段&#xff0c;数据库&#xff0c;表&#xff0c;列&#xff0c;索引等数据库对象的定义。常用的语句关键字主要包括…

spark shuffle写操作——BypassMergeSortShuffleWriter

创建分区文件writer 每一个分区都生成一个临时文件&#xff0c;创建DiskBlockObjectWriter对象&#xff0c;放入partitionWriters 分区writer写入消息 遍历所有消息&#xff0c;每一条消息都使用分区器选择对应分区的writer然后写入 生成分区文件 将分区writer的数据flu…

强烈建议!所有Python基础差的同学,死磕这本64页的背记手册!

Python背记手册是一份非常实用的学习资料&#xff0c;它涵盖了Python语言的基础知识、语法规则、常用函数和模块等内容&#xff0c;对于初学者和有一定基础的Python程序员来说都非常有用。通过背诵这份手册&#xff0c;可以加深对Python语言的理解和记忆&#xff0c;提高编程能…

百度云智能媒体内容分析一体机(MCA)建设

导读 &#xff1a;本文主要介绍了百度智能云MCA产品的概念和应用。 媒体信息海量且复杂&#xff0c;采用人工的方式对视频进行分析处理&#xff0c;面临着效率低、成本高的困难。于是&#xff0c;MCA应运而生。它基于百度自研的视觉AI、ASR、NLP技术&#xff0c;为用户提供音视…

RFID电子锁在物流货运智能锁控管理的创新方案

物流货运锁控的现实挑战 易损性&#xff1a;传统锁具易受物理破坏&#xff0c;无法抵御恶意撬锁。 低效率&#xff1a;依赖人工操作&#xff0c;开锁速度慢&#xff0c;影响作业效率。 高成本&#xff1a;钥匙的制作、管理和丢失替换成本高昂。 监控缺陷&#xff1a;缺乏实…

笔记本如何录屏?3个方法分享给你

随着科技的飞速发展&#xff0c;录屏功能已不再局限于传统的教育或游戏领域&#xff0c;而是成为了大众都能用得到的创作、分享、记录生活的得力助手。同时&#xff0c;在生活中人们更多地使用到笔记本电脑&#xff0c;笔记本电脑有着其便携性、高效能和丰富软件资源&#xff0…

8.13 矢量图层面要素反转面要素渲染(Inverted polygons Renderer)

前言 本章介绍矢量图层面要素反转面要素(Inverted polygons Renderer)的使用说明&#xff1a;文章中的示例代码均来自开源项目qgis_cpp_api_apps 反转面要素(Inverted polygons Renderer) 反转面要素渲染常用于掩膜数据。 反转面要素(Inverted polygons Renderer)是一种渲染方…

python库(2):Passlib库

1 Passlib简介 Passlib库就是一个强大的工具&#xff0c;专门用于密码的安全存储和验证。本文将介绍Passlib库的基本概念、功能和使用方法&#xff0c;帮助更好地理解和应用密码安全技术。 Passlib是一个用于密码加密、哈希和验证的Python库&#xff0c;它提供了多种密码哈希…

adb不插usb线通过wifi调试

说起做手机开发也有好多年了&#xff0c;说来惭愧&#xff0c;我最近才知道安卓手机是可以不插数据线进行开发调试的。起因是公司近期采购了一批安卓一卡通设备&#xff0c;需要对其进行定制开发APP,但是由于我插USB调试发现没有反应。通过询问厂家才知道可以通过WIFI进行调试。…