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

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.xdnf.cn/news/1472650.html

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

相关文章

【读点论文】基于二维伽马函数的光照不均匀图像自适应校正算法

基于二维伽马函数的光照不均匀图像自适应校正算法 摘 要:提出了一种基于二维伽马函数的光照不均匀图像自适应校正算法.利用多尺度高斯函数提取出场景的光照分量,然后构造了一种二维伽马函数,并利用光照分量的分布特性调整二维伽马函数的参数,降低光照过强区域图像的亮度值,提高…

惠海 H6225K 降压恒压芯片 支持12V24V36V48V60V转3.3V 5V车载仪器仪表方案

H6225K是一种内置60V耐压MOS&#xff0c;支持输入高达48V的高压降压开关控制器&#xff0c;可以向负载提供2.5A的连续电流。H6225K支持输出恒定电压&#xff0c;可以通过调节VFB采样电阻来设置输出电压&#xff0c;同时支持最大电流限制&#xff0c;可以通过修改CS采样电阻来设…

期权学习必看圣书:《3小时快学期权》要在哪里看?

今天带你了解期权学习必看圣书&#xff1a;《3小时快学期权》要在哪里看&#xff1f;《3小时快学期权》是一本关于股票期权基础知识的书籍。 它旨在通过简明、易懂的语言和实用的案例&#xff0c;让读者在短时间内掌握股票期权的基本概念、操作方法和投资策略。通过这本书&…

Python酷库之旅-第三方库Pandas(004)

目录 一、用法精讲 5、pandas.DataFrame.to_csv函数 5-1、语法 5-2、参数 5-3、功能 5-4、返回值 5-5、说明 5-6、用法 5-6-1、代码示例 5-6-2、结果输出 6、pandas.read_fwf函数 6-1、语法 6-2、参数 6-3、功能 6-4、返回值 6-5、说明 6-6、用法 6-6-1、代码…

从海上长城到数字防线:视频技术在海域边防现代化中的创新应用

随着全球化和科技发展的加速&#xff0c;海域安全问题日益凸显其重要性。海域边防作为国家安全的第一道防线&#xff0c;其监控和管理面临着诸多挑战。近年来&#xff0c;视频技术的快速发展为海域边防场景提供了新的解决方案&#xff0c;其高效、实时、远程的监控特点极大地提…

QWidget成员函数功能和使用详细说明(四)(文字+用例+代码+效果图)

文章目录 1.测试工程配置2.成员函数2.1 void setParent(QWidget *parent)2.2 void setMouseTracking(bool enable)2.3 bool hasMouseTracking() const2.4 void setPalette(const QPalette &)2.5 const QPalette &palette() const2.6 int QWidget::grabShortcut(const Q…

Java 并发集合:CopyOnWrite 写时复制集合介绍

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 016 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

【深度学习】图形模型基础(5):线性回归模型第二部分:单变量线性回归模型

1.引言 在统计学与机器学习的广阔领域中&#xff0c;线性回归作为一种基础而强大的预测技术&#xff0c;其核心在于通过输入变量&#xff08;或称预测器、自变量&#xff09;来估计输出变量&#xff08;响应变量、因变量&#xff09;的连续值。本章聚焦于线性回归的一个基本但…

hnust 1815: 算法10-6~10-8:快速排序

hnust 1815: 算法10-6~10-8&#xff1a;快速排序 题目描述 快速排序是对起泡排序的一种改进。它的基本思想是&#xff0c;通过一趟排序将待排序的记录分割成两个独立的部分&#xff0c;其中一部分记录的关键字均比另一部分的关键字小&#xff0c;在分成两个部分之后则可以分别…

记一次漏洞挖掘【网络安全】

漏洞信息 从CVE-2019-10999查看该CVE的基础信息得知&#xff0c;这是一个栈溢出漏洞&#xff0c;攻击者在已登录的情况下可以通过向wireless.htm发送一个超长的WEPEncryption参数导致栈溢出&#xff0c;从而执行任意命令攻击. 现在我们利用Shambles Desktop工具确定这个漏洞的…

OpenCV基础(2)

目录 滤波处理 均值滤波 基本原理 函数用法 程序示例 高斯滤波 基本原理 函数用法 程序示例 中值滤波 基本原理 函数用法 程序示例 形态学 腐蚀 膨胀 通用形态学函数 前言&#xff1a;本部分是上一篇文章的延续&#xff0c;前面部分请查看&#xff1a;OpenCV…

计算机网络之以太网

上文内容&#xff1a;总线局域网以及冲突的解决方法 1.以太网的起源 1.1起源 60年代末期&#xff0c;夏威夷大学Norman Abramson等研制ALOHA无线网络系统,实现Oahu岛上的主机和其它岛及船上的读卡机和终端通信&#xff1b; 出境信道地址&#xff1a;主机到终端&#xff1…

空间数据获取与预处理指南:生产与科研应用

1.空间数据简介 2.免费的国外GIS数据下载方法 3.免费的国内GIS数据下载方法 4.遥感云平台数据的获取方法 5.专题数据的获取及预处理示例 (1)行政区划数据 (2)气象数据 (3)土壤数据 (4)遥感产品数据 (5)统计数据 (6)…… 原文链接https://mp.weixin.qq.com/s?__bizMz…

Mean teacher are better role models-论文笔记

论文笔记 资料 1.代码地址 2.论文地址 https://arxiv.org/pdf/1703.01780 3.数据集地址 CIFAR-10 https://www.cs.utoronto.ca/~kriz/cifar.html 论文摘要的翻译 最近提出的Temporal Ensembling方法在几个半监督学习基准中取得了最先进的结果。它维护每个训练样本的标签…

打赢网络免疫升级战!看聚铭铭察高级威胁检测系统如何重塑网络安全防线

在信息洪流的今天&#xff0c;企业如航行于暗礁密布的数字海洋&#xff0c;面对的不仅仅是已知的病毒与漏洞&#xff0c;更有高级威胁这股暗流&#xff0c;悄无声息地侵蚀着网络的肌理。常规的安全措施&#xff0c;犹如常规体检&#xff0c;虽能捕捉表面的异常&#xff0c;却难…

竹云实力入选《现代企业零信任网络建设应用指南报告》代表性厂商

2024年7月3日&#xff0c;国内网络安全媒体安全牛正式发布《现代企业零信任网络建设应用指南报告(2024版)》。竹云凭借在零信任领域创新性的产品方案和优异的市场表现&#xff0c;实力入选代表性厂商。 伴随着云计算、AI、大数据等技术的发展&#xff0c;远程办公、业务协同、…

spring boot 接口参数解密和返回值加密

spring boot 接口参数解密和返回值加密 开发背景简介安装配置yml 方式Bean 方式 试一下启动项目返回值加密参数解密body 参数解密param和form-data参数解密 总结 开发背景 虽然使用 HTTPS 已经可以基本保证传输数据的安全性&#xff0c;但是很多国企、医疗、股票项目等仍然要求…

聚鼎科技:装饰画现在做晚不晚

在每一处光影交错的角落&#xff0c;墙上那一副副静默无言的装饰画&#xff0c;似乎总在诉说着不同的故事。如今&#xff0c;投身于装饰画的创作与收藏&#xff0c;仿佛是一场关于美和时间的赛跑&#xff0c;那么问题来了——现在开始&#xff0c;晚吗? 伴随着生活品质的提升和…

长难句打卡7.5

When the United States entered just such a glowing period after the end of the Second World War, it had a market eight times larger than any competitor, giving its industries unparalleled economies of scale. 二战结束后&#xff0c;美国恰好进入了这样一段辉煌…

从草图到现实:SketchUp 在建筑项目中的独特优势

Sketchup 是全球最受欢迎的建筑可视化平台之一。借助该平台提供的各种工具&#xff0c;您可以创建可供市场使用的逼真项目。Sketchup为什么如此优秀&#xff1f;它对建筑项目有哪些优势&#xff1f;下面&#xff0c;你将看到什么是 Sketchup 以及这个工具的一些重要的优势。 关…