什么是C ++中的“翻译单位”


236

当时我正在阅读Meyers撰写的“ Effective C ++”,遇到了“翻译单元”一词。

有人可以给我一个解释:

1)到底是什么

2)在用C ++编程时应何时考虑使用它

3)如果仅与C ++有关,或者可以与其他编程语言一起使用

我可能已经在不知道该术语的情况下使用它了。


1
2.如果已包含头文件,则您已经在使用翻译单元。这是一个仅供参考的术语,而不是一个c ++构造
talekeDskobeDa

Answers:


268

这里开始:(Wayback Machine链接

根据标准C ++回程机器链接):翻译单元是C ++中编译的基本单元。它由单个源文件的内容以及直接或间接包含的任何头文件的内容组成,减去那些使用条件预处理语句忽略的行。

单个翻译单元可以编译为目标文件,库或可执行程序。

在“一个定义规则”和模板的上下文中最经常提到翻译单元的概念。


9
该术语仅在C / C ++中使用吗?
dekuShrub

2
@dekuShrub实际上,不是。例如,在Rust中,翻译单元是板条箱,在C ++中,相同的东西将被称为整个库。该术语本身具有通用性,但绝对以C.
Sahsahae 19/12/6

新参考书大致说明了该答案的内容:en.wikipedia.org/wiki/Translation_unit_
Gabriel Staples

67

翻译单元是所有意图和目的文件(.C /的.cpp),之后它的完成,包括所有的头文件。

http://msdn.microsoft.com/zh-CN/library/bxss3ska%28VS.80%29.aspx


3
包括头文件。头文件由编译器处理,即使未生成任何代码。另请参阅JeffH的预处理程序注释,“编译器看到的所有内容”定义是一个很好的定义。
Marco van de Voort,2009年

10
您可以编译以“ .h”结尾的文件。文件名根本不重要。内容是。如果“ foo.h”的内容是“ int main(){}”,则可以对其进行编译。
Johannes Schaub-litb

@LightnessRacesinOrbit:是的,我要说的是将标头直接编译为TU,而不是通过包含将其间接编译为TU是不合常规的。删除第一个注释是完全错误的,保留第二个注释以提供新的上下文。
GManNickG

1
@GManNickG:““ .h文件通常不直接馈送到编译器。”
Lightness Races in Orbit

@ JohannesSchaub-litb我认为您的意思是链接,而不是编译。您可以编译任何文件,只要它是定义了所有名称的正确C / C ++。编译头文件是没有用的,因为头文件的整个要点都将被包含(读取复制)到源文件中,因此在编译包含它的源文件时已经对它们进行了编译。我想您想说的是,您无法从没有主要功能的文件中创建可执行文件。
pooya13

30

一个很难回答的问题。C ++标准规定:

程序的文本保留在此国际标准中称为源文件的单元中。通过预处理指令#include将源文件连同所有标头(17.4.1.2)和包含的源文件(16.2)一起,减去通过任何条件包含(16.1)预处理指令跳过的任何源行,称为转换单元。[注意:一个C ++程序不需要全部同时翻译。]

因此,对于大多数意图和目的而言,翻译单元是单个C ++源文件以及通过预处理器#include机制包含的头文件或其他文件。

关于您的其他问题:

2)在用C ++编程时应何时考虑使用它

您不能不考虑它-翻译单元是C ++程序的基础。

3)如果仅与C ++有关,或者可以与其他编程语言一起使用

其他语言也有类似的概念,但是它们的语义会有所不同。例如,大多数其他语言不使用预处理器。


1
我不知道这是否澄清。这可能是一个有点模糊的区域-例如,从我引用的标准参数中尚不清楚,我引用了预编译的头文件。

1
@GMan,这是您必须非常注意一个定义规则的地方。如果您在不同的翻译单元中包含一个类,并且在定义之前稍有不同,则该类会导致该类具有不同的代码,这将导致未定义的问题。
马特·普赖斯

6
@GMan注意标准使用的两个术语:“标题”和“源文件”。“标头”仅用于标准库。某些代码包含的用户文件在标准中不称为“标头”,而在“源文件”中称为“标头”。标准不知道我们可怜的c ++程序员组成的“ .h”和“ .cpp”之间的区别:)
Johannes Schaub-litb

8

这本书讲得很清楚。当Meyers引用“翻译单元”时,他表示源代码文件。


1
不。如果他在谈论源代码,他会说源文件。翻译单元是通过编译源代码制成的。注意明显的不同。它是“翻译的”源代码。
2014年

3
@丹:不,不是。转换单元是包含之后可以编译的源文件,即编译之前预处理器的输出。
Ed S.

1
实际上,尽管有C ++标准的称呼,“翻译单元”通常用于传达单个已编译代码“单元”的思想。实际上,根据Microsoft编译人员的说法,您直接链接“翻译单元”。 msdn.microsoft.com/en-us/library/vstudio/…– 2014
丹,

1
那么,我们是要成为“ C ++标准”纳粹分子,还是我们要帮助人们与行业中的其他人进行交流?我知道这是一个C ++线程,所以我不会介绍xcode所谓的tu。或该术语的所有其他定义。
2014年

1
@丹:翻译单位是标准所称的单位。我并不真正关心随机编译器开发人员的意见。有趣的是,那个挖了一个将近五年的职位来挑剔,并告诉我我的定义是错误的家伙转过身来,称我为“纠正他的语言纳粹”。是的,继续前进,您很累。
Ed S.

4

除了ODR之外,转换单元在未命名名称空间的定义中也很重要,它取代了“静态”的一种古老用法。

我想我仍然没有足够的要点在最佳答案下添加评论。


3

翻译单元是传递给适当的编译器的代码。这通常意味着在.c文件上运行预处理器的输出。


2

C和C ++程序由一个或多个源文件组成,每个文件都包含程序的某些文本。源文件及其包含文件(使用#include预处理程序指令包含的文件)一起但不包括被条件编译指令(例如#if)删除的代码段,称为“翻译单元”。


1

根据MSDN:C和C ++程序由一个或多个源文件组成,每个文件都包含该程序的某些文本。源文件及其包含文件(使用#include预处理程序指令包含的文件)一起但不包括被条件编译指令(例如#if)删除的代码段,称为“翻译单元”。


0

每个cpp / c(实现)文件都将转换为转换单元(即目标文件(.obj))。cpp文件中的头文件将替换为头文件中的实际文本。


0

正如其他人所说,翻译单元基本上是经过预处理的源文件的内容。它是语言语法中最重要的内容。如果您正在编写C或C ++编译器,则只需担心它。


1
“如果您正在编写C或C ++编译器,则只需担心它。” 我不同意:程序员经常需要了解编译器在做什么。因此,例如,您需要知道什么是转换单元才能理解有效C ++中第5项的要点:“未定义在不同转换单元中定义的非本地静态对象的初始化的相对顺序”。
Channing Moore

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.