【问题标题】:Building an executable out if a single cpp file [duplicate]如果单个cpp文件[重复]构建可执行文件
【发布时间】:2019-09-11 05:28:24
【问题描述】:

我知道有类似的帖子,但我觉得我的问题足够具体,仍然可以提问。 假设我选择通过将实际定义放入头文件中来构建可执行文件,然后将它们全部包含在单个 cpp 文件中。

如果我理解正确,它的含义只会影响构建过程,即编译和链接,而不会影响运行时性能。是真的吗?

此外,编译时间应该更长,而链接时间应该更低。不应该是这样吗?如果不是这样,编译时间增加真的是没有人构建这样的应用程序的唯一原因吗?

【问题讨论】:

  • 实际的问题是您每次都必须重新构建您的整个代码,即使是在对它进行最微小的更改之后。对于可能需要数小时的大型项目(例如,尝试从源代码构建 Clang)。如果您首先构建目标文件或库,那么您只需要重新构建该特定库或二进制文件的文件。
  • 与编译相比,链接速度快得惊人,而且两者都比在一个字面上一团糟的项目中工作要快。您的提议与语言和围绕它的工具(包括编译器)的设计目的相反,并且没有任何版本可以正确运行。
  • 实际上,它可以对运行时性能产生很大影响,以至于工具链提供了执行此操作的选项(“整个程序优化”),即使在一堆单独的编译单元上调用也是如此。请参阅链接的问题。
  • @BenVoigt 即使这样你也可以使用 #include 代替。
  • @Havenard:仅当代码的结构不会在文件范围内发生命名冲突。

标签: c++


【解决方案1】:

编译过程的简短 TL;DR。编译器首先运行执行预处理器指令的预处理器(即开头带有哈希的行,例如包含)。

include 指令只是将一个文件的内容复制到另一个文件中。因此,在包含的文件(通常是头文件)中移动内容在这方面并没有太大变化。我们只是取出定义,因为每个翻译单元(在预处理器运行后将其视为 .cpp,插入包含的文件)必须对每个事物只有一个定义。在标头中有定义使得这很难避免。

所以,一个翻译单元的编译也差不多。除了多重定义之外,问题在于当一个头被修改时,所有其他包含它的文件都必须重新编译。如果它是一个广泛使用的标头,这可能需要一段时间。另一方面,如果一个 .cpp 文件被修改,只有它被重新编译。

由于预处理器主要进行文本操作,因此可执行文件应该是相同的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-10
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 2018-09-15
    • 2020-01-16
    • 2018-12-29
    • 2016-12-08
    相关资源
    最近更新 更多