编译/链接过程如何进行?

2024-02-29

编译和链接过程如何进行?

(Note: This is meant to be an entry to Stack Overflow's C++ FAQ https://stackoverflow.com/questions/tagged/c++-faq. If you want to critique the idea of providing an FAQ in this form, then the posting on meta that started all this https://meta.stackexchange.com/questions/68647/setting-up-a-faq-for-the-c-tag would be the place to do that. Answers to that question are monitored in the C++ chatroom https://chat.stackoverflow.com/rooms/10/c-lounge, where the FAQ idea started out in the first place, so your answer is very likely to get read by those who came up with the idea.)


C++程序的编译包括三个步骤:

  1. 预处理:预处理器获取 C++ 源代码文件并处理#includes, #defines 和其他预处理器指令。此步骤的输出是一个“纯”C++ 文件,没有预处理器指令。

  2. 编译:编译器获取预处理器的输出并从中生成目标文件。

  3. 链接:链接器获取编译器生成的目标文件并生成库或可执行文件。

预处理

预处理器处理预处理器指令, like #include and #define。它与 C++ 的语法无关,因此必须小心使用。

它通过替换一次处理一个 C++ 源文件#include指令与各个文件的内容(通常只是声明),进行宏的替换(#define),并根据以下情况选择文本的不同部分#if, #ifdef and #ifndef指令。

预处理器对预处理标记流进行工作。宏替换被定义为用其他标记替换标记(运算符##允许在有意义时合并两个令牌)。

所有这些之后,预处理器会生成一个输出,该输出是由上述转换产生的标记流。它还添加了一些特殊标记,告诉编译器每行来自哪里,以便编译器可以使用这些标记来生成合理的错误消息。

如果巧妙地使用此阶段,可能会产生一些错误#if and #error指令。

汇编

编译步骤对预处理器的每个输出执行。编译器解析纯 C++ 源代码(现在没有任何预处理器指令)并将其转换为汇编代码。然后调用底层后端(工具链中的汇编器),将该代码汇编成机器代码,以某种格式(ELF、COFF、a.out 等)生成实际的二进制文件。该目标文件包含输入中定义的符号的编译代码(二进制形式)。目标文件中的符号通过名称引用。

目标文件可以引用未定义的符号。当您使用声明但不为其提供定义时就会出现这种情况。编译器不介意这一点,只要源代码格式良好,就会很乐意生成目标文件。

编译器通常会让您在此时停止编译。这非常有用,因为使用它您可以单独编译每个源代码文件。这样做的好处是不需要重新编译一切如果您只更改一个文件。

生成的目标文件可以放入称为静态库的特殊档案中,以便以后更轻松地重用。

正是在这个阶段,报告“常规”编译器错误,例如语法错误或失败的重载解析错误。

Linking

链接器从编译器生成的目标文件中生成最终编译输出。此输出可以是共享(或动态)库(虽然名称相似,但它们与前面提到的静态库没有太多共同点)或可执行文件。

它通过用正确的地址替换对未定义符号的引用来链接所有目标文件。这些符号中的每一个都可以在其他目标文件或库中定义。如果它们是在标准库以外的库中定义的,则需要告诉链接器它们。

在此阶段,最常见的错误是缺少定义或重复定义。前者意味着定义不存在(即未编写),或者它们所在的目标文件或库未提供给链接器。后者是显而易见的:在两个不同的目标文件或库中定义了相同的符号。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编译/链接过程如何进行? 的相关文章

  • 警告:从指针目标类型中丢弃“const”限定符

    没有const char s意味着 s 是一个指向常量 char 的指针 那么为什么它给我这个警告 我并不是想改变价值观 在第一个函数中警告是return discards const qualifiers from pointer tar
  • 如何使用 C# 打印 pdf

    我在 C 应用程序中使用 进程 打印 pdf 文件 但是我无法获取打印状态 我发现可以通过 System management 和 System printing 与打印机 队列进行交互 我做了很多尝试 但都出错了使用这两个命名空间但无法打
  • boost::interprocess 准备好迎接黄金时间了吗? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在开发一个由内存映射文件支持的线
  • C#9 顶级语句文件上的属性

    我正在尝试向顶级语句文件添加属性 但没有找到任何相关信息 是否可以 对于某些上下文 我想仅在该文件中禁用规则 SuppressMessage StyleCop CSharp LayoutRules SA1516 ElementsMustBe
  • 何时对向量进行归一化?

    我正在学习 XNA 并且在几乎所有的教育套件中都可以找到http creators xna com en US http creators xna com en US 我总是看到向量上对 Normalize 的调用 我知道归一化基本上将向量
  • C/C++ 中随机数生成器的实现[重复]

    这个问题在这里已经有答案了 我对 C 中随机数生成器的实现有点困惑 它也与 C 中的明显不同 如果我理解正确 对 srand seed 的调用会以某种方式初始化可通过 rand 访问的隐藏变量 种子 该变量又将函数指向预先生成的序列 例如例
  • 如何将 C++ 类包装在基于 C 的 dll 或基于 CLI 的 dll 中?

    我被告知将我用 C 编写的类导入到 dll 中 然后在 c 应用程序中使用该 dll 下列的本指南 https stackoverflow com questions 4555961 how to use a class in dll我创建
  • 实体框架7审计日志

    我正在将一个旧项目移植到 ASP NET 5 和 Entity Framework 7 我使用数据库优先方法 DNX 脚手架 来创建模型 旧项目基于Entity Framework 4 审计跟踪是通过重写实现的SaveChanges的方法D
  • initializer_list 和默认构造函数重载决策

    include
  • 我们应该使用 Eval 还是 Databind 事件?

    当使用 Asp Net 并使用 ListView 等控件创建网站时 使用 Eval 命令是一个好习惯吗 还是应该在 databind 事件中填充文字和数据 取决于您是否想在更新事件上写回数据 在这种情况下数据绑定 如果您只想读取该数据 可以
  • IBM Watson 对话服务错误:无法从“方法组”转换为“conversation.onMessage”

    我正在尝试运行 IBM Watson会话服务团结和下面是代码片段 https github com watson developer cloud unity sdk conversation private Conversation m C
  • 在 C# 中生成随机值

    如何使用以下命令生成随机 Int64 和 UInt64 值RandomC 中的类 这应该可以解决问题 这是一个扩展方法 因此您可以像调用普通方法一样调用它Next or NextDouble上的方法Random目的 public stati
  • 使用 cudamalloc()。为什么是双指针?

    我目前正在浏览有关的教程示例http code google com p stanford cs193g sp2010 http code google com p stanford cs193g sp2010 学习CUDA 演示的代码 g
  • 打破条件变量死锁

    我遇到这样的情况 线程 1 正在等待条件变量 A 该变量应该由线程 2 唤醒 现在线程 2 正在等待条件变量 B 该变量应该由线程 1 唤醒 在我使用的场景中条件变量 我无法避免这样的死锁情况 我检测到循环 死锁 并终止死锁参与者的线程之一
  • 为什么我的 ITexthandler 不工作?我正在尝试将 XML 解析为 ITextSharp 文档

    我正在使用 Visual Developer 2010 MVC 3 c 我正在尝试将 XML 解析为 iTextSharp 文档 如下所示 ITextHandler textHandler new ITextHandler doc text
  • 如果数组为空,LINQ 返回 null

    public class Stuff public int x other stuff 我有一个IEnumerable
  • C# - 命名空间内的类型声明

    在命名空间内而不是在类中声明类型的可能用途是什么 For ex namespace Test public delegate void Ispossible 这是有效的并且不会产生任何编译错误 但我无法想象为什么我们会以这种方式声明它而不是
  • 获取大于某个数字的元素个数

    我正在尝试解决以下问题 数字被插入到容器中 每次插入数字时 我需要知道容器中有多少元素大于或等于当前插入的数字 我相信这两个操作都可以以对数复杂度完成 我的问题 C 库中有标准容器可以解决这个问题吗 我知道std multiset可以在对数
  • Crypto++ 和压缩 EC 密钥

    如何在 Crypto 中生成压缩的 ECDSA 密钥 AutoSeededRandomPool prng ECDSA
  • 请解释为什么Java和C对此代码给出不同的答案

    public class Test public static void main String args int i 10 i i System out println value of i is i 输出是 10 当我在中执行类似的代码

随机推荐

  • 在 Android 中实现 websocket 客户端的简单方法是什么?下面的例子正确吗?

    我试图使用一个在 Android 中实现 WebSocket 客户端的类 但我收到以下错误 12 07 11 22 46 286 31579 31579 com domain wsocketchat W System ClassLoader
  • CFNetwork 内部错误:CFNetworkInternal.h:478

    我的 iOS 设备日志 在模拟器和真实设备上 充满了几十行以下错误垃圾邮件 CFNetwork 内部错误 0xc01a BuildRoot Library Caches com apple xbs Sources CFNetwork Sim
  • 向 Ember.TextField 添加名称属性?

    这是漫长的一天 这可能非常简单 但是如何向 Ember TextField 添加名称属性 我想做这样的事情 view Ember TextField valueBinding your name placeholder Your name
  • 任务并行库 - 自定义任务调度程序

    我需要向在线 api 发出 Web 服务请求 我认为并行扩展非常适合我的需求 所涉及的网络服务被设计为重复调用 但有一种机制 如果每秒的调用次数超过一定数量 就会向您收费 我显然想最大程度地减少费用 因此想知道是否有人见过可以满足以下要求的
  • 在 Swift fileExistsAtPath(_ path: String, isDirectory isDirectory: UnsafeMutablePointer) 中 -> Bool 仅接受单个参数

    下面示例中的方法 fileExistsAtPath 仅接受单个参数 if fm fileExistsAtPath result isDirectory isDir 确切的错误消息是 调用中存在额外参数 isDirectory 知道出了什么问
  • 10以下的int值转换为字符串两位数字

    string strI for int i 1 i lt 100 i strI i ToString 在这里 如果i 1 then ToString yields 1 但我想得到 01 or 001 看起来很简单 但只有一篇文章关于 dat
  • 什么是 DataGridView.Rows.Clear()?

    我每隔一定时间就会以编程方式在 datagridview 中添加一些行 我想在datagridview中查看某些github存储库的状态 例如是否在线 特定时间存储库中有多少提交等 因此 当超时时 我使用 DataGridView Rows
  • Pyomo:使用 if 语句进行约束

    我目前正在努力解决这个问题 我需要最大化这家公司的利润 这就是我目前拥有的代码 from pyomo environ import from pyomo opt import opt solvers SolverFactory ipopt
  • 使用 Google 的 C++ Native Client 的 HTTP POST 请求

    如何使用 Google 的 C Native Client 执行 HTTP POST 请求 这个问题很久以前就被问过 但以防万一其他人也想知道同样的事情 您可以使用pp URLRequestInfo SetMethod https deve
  • 流行 Android 手机支持的相机预览尺寸

    我正在使用相机预览帧 并且需要决定我将使用的最小预览尺寸 我需要相当高的分辨率 并且正在尝试找出我可以在更流行的 Android 手机和操作系统版本上获得的最高预览分辨率 根据判断关于 Nexus One Froyo 预览尺寸的问题 htt
  • 使用显式与隐式意图启动 Android 服务

    根据标准 Android 文档 启动服务 即启动服务 的首选方法是使用如下所示的显式意图 Using explicit intent Intent serviceIntent new Intent getApplicationContext
  • 如何将 package.json 版本写入我的 WebPack 捆绑包?

    我的 package json 文件包含我的模块的版本 该版本最终被编译到我包含在我的 Web 项目中的 app bundle js 文件中 我真的很想将 package json 文件中的版本号写入 app bundle js 文件 作为
  • 按创建日期对 glob() 进行排序 [重复]

    这个问题在这里已经有答案了 我在用 foreach glob config pages php as page 获取目录中所有文件的列表config pages 我可以先显示最旧的文件 最后显示最新的文件吗 我想用所有这些制作一个导航菜单
  • 发送聊天消息

    我有这个代码 var msg new ChatMessage msg Body Test msg Recipients Add number var cms await ChatMessageManager RequestStoreAsyn
  • 使用基类作为 WCF 服务的参数

    我有一个多项目解决方案 一个项目提供一个包含多个类的 DLL 其中一门课是WorkerTemplate 另外两个类继承自它 即ExecSQLWorker and CopyWorker class ExecSQLWorker WorkerTe
  • 无服务器:在 ubuntu 16.04 中找不到命令

    我正在尝试在 Ubuntu 16 04 LTS 中设置 AWS Serverless 框架 我安装了 Node js 并且还使用以下命令安装了 Serverless npm install g serverless在终端中 但当我尝试跑步时
  • PowerShell ForEach / 管道混乱

    我正在 PowerShell 中使用 TFS PowerTools Cmdlet 尝试从我的服务器获取有关变更集和相关工作项的一些信息 我已将问题归结为我不理解的行为 我希望它不是 TFS 特定的 所以那里的人可能能够向我解释问题 这是我可
  • C# 中的内部类

    直到最近我才知道普通类和内部类 子类之间有区别 内部类的实例与其包含类的实例之间有什么关系 内部类的目的是什么以及它们有何不同 与 Java 不同 C 包含的类是嵌套的 包含类实例和被包含类实例之间没有关系 包含类仅在 C 中用于控制包含类
  • 使用 Jackson 根据 API 版本指定不同的 JSON 属性名称

    我需要能够使用 Jackson 序列化 反序列化对象同时支持多个 API 版本 我探索过以下解决方案 JsonProperty 属性命名策略 混合注解 然而 每一个都会导致自己的问题 如果我可以直接在注释中添加具有正确名称的多个版本 Jso
  • 编译/链接过程如何进行?

    编译和链接过程如何进行 Note This is meant to be an entry to Stack Overflow s C FAQ https stackoverflow com questions tagged c faq I