Luc*_*ore 24 c++ compiler-construction compilation c++-faq
是否由标准指定的C++程序的编译阶段?
如果是这样,他们是什么?
如果没有,广泛使用的编译器(我更喜欢MSVS)的答案会很棒.
我在谈论预处理,标记化,解析等.它们的执行顺序是什么,特别是它们的作用是什么?
编辑:我知道编译,链接和预处理是做什么的,我最感兴趣的是其他人和订单.当然,对这些的解释也受到欢迎,因为我可能不是唯一对答案感兴趣的人.
Kei*_*son 38
是否由标准指定的C++程序的编译阶段?
是的,不是.
C++标准定义了9个"翻译阶段".引用N3242草案(10MB PDF),日期为2011-02-28(官方C++ 11标准发布之前),第2.2节:
翻译语法规则的优先级由以下阶段指定[见脚注].
- 如果需要,物理源文件字符以实现定义的方式映射到基本源字符集(引入行尾指示符的换行符).[SNIP]
- 删除反斜杠字符(\)后面紧跟一个新行字符的每个实例,拼接物理源代码行以形成逻辑源代码行.[SNIP]
- 源文件被分解为预处理标记(2.5)和空白字符序列(包括注释).[SNIP]
- 执行预处理指令,扩展宏调用,并执行_Pragma一元运算符表达式.[SNIP]
- 字符文字或字符串文字中的每个源字符集成员,以及字符文字或非原始字符串文字中的每个转义序列和通用字符名称,都将转换为执行字符集的相应成员; [SNIP]
- 相邻的字符串文字标记是连接的.
- 分隔标记的空白字符不再重要.每个预处理令牌都转换为令牌.(2.7).由此产生的标记在语法和语义上进行分析并翻译为翻译单元.[SNIP]
- 翻译的翻译单元和实例化单元组合如下:[SNIP]
- 解析所有外部实体引用.链接库组件以满足对当前转换中未定义的实体的外部引用.所有这样的翻译器输出被收集到程序映像中,该程序映像包含在其执行环境中执行所需的信息.
[脚注]实现必须表现得好像发生了这些不同的阶段,尽管实际上不同的阶段可能会折叠在一起.
正如[SNIP]标记所示,我没有引用整个部分,只是足以让我们了解这个想法.
要强调的是,编译器并不需要遵循这个精确模型,只要最后的结果是,如果他们做到了.
阶段1-6或多或少地对应于预处理器,7对应于您通常认为的编译,8处理模板,9对应于链接.
(C的翻译阶段类似,但#8被省略.)
9个所谓的"翻译阶段"列在标准中[lex.phases](2.2 in C++ 11,2.1 in C++ 03).
标准中要求的细节各不相同:预处理分为几个阶段,因为它在标准中的各个点上非常重要,正是"已经完成"以及在定义特定行为时"剩下要做什么".因此虽然它没有告诉你如何编写词法分析器,但它为你提供了一个非常清晰的路线图.
另一方面,链接主要留给实现来决定它实际上是如何实现的,因为标准并不关心如何查找给定名称,只是它所指的是什么.
它没有给出任何关于解析的细节,它只是说"所得到的标记在语法和语义上被分析和翻译".那是因为整个第3-15章都需要填写这些细节.
它根本没有提到解析/翻译过程中的内部表示,也没有提到优化阶段 - 它们对编译器的设计很重要,但它们对标准并不重要.优化可以在不同编译器的不同位置进行.很长一段时间,优化几乎完全在编译阶段,在发出目标文件之前,并且链接器作为帖子是愚蠢的.我认为现在严肃的C++实现都可以在多个TU中进行至少一些优化.所以"其他人"不仅仅被排除在标准之外,他们确实会随着时间的推移而改变.