【问题标题】:Do I need .CPP files at all? Use headers only and make everything inline?我需要 .CPP 文件吗?仅使用标题并使所有内容都内联?
【发布时间】:2011-12-18 13:32:13
【问题描述】:

特别是 GCC 4.6.1。

我知道 CPP 文件用于将接口与实现分开;现在不感兴趣。

看看this,我看不出有什么理由不只使用标题和所有内联函数。

性能是一个问题,但我认为这种方法不会让事情变慢。我不想要的是让通常是内联的关键部分变得更慢,因为 everything 是内联的。如果这有意义的话。

【问题讨论】:

  • 将所有源文件连接成一个巨大的源文件用于发布版本是一种常见的技巧...... GCC 有-fwhole-program 可以在这种情况下实现更彻底的优化。新的-flto 在没有人工干预的情况下基本上做同样的事情。不要太担心它,编写程序以便下一个人能够理解并继续它们。
  • 好吧,从技术上讲,编译器并不关心头文件和实现文件——它们是 C 文件,一些包含声明,一些包含定义。但是内联所有内容并不能提高性能 - 编译器对此相当谨慎是有原因的(例如,它会使缓存变得混乱)。
  • 您认为您会从中获得什么好处?

标签: c++ gcc g++ inline header-files


【解决方案1】:

真正的主要问题是编译时间。

如果所有内容都包含在单个“主”编译单元中,那么如果您更改单个文件中的单个字符,则必须重新编译所有内容。

另一方面,与使用多个编译单元相比,完全重建很可能更快(在这种情况下,必须多次编译相同的头文件,并且链接器会有更多工作要做。使用单个编译单元,每个头只需要处理一次,链接器的工作很简单)

对于多个 .cpp 文件,您可以对其中一个进行更改,而只需重新编译 那个 文件。

但是一些流行的库是只有头文件的。这绝对是可行的。

在性能方面,它应该相同或更快。您为编译器提供了对整个代码的完全可见性,这意味着它可以轻松地跨函数调用进行优化,并内联它喜欢的任何内容。

请注意,您永远不会强制编译器内联。 inline 关键字(和其他具有相同效果的技巧)不会告诉编译器“必须内联”。但是通过抑制单一定义规则 (ODR),它们允许您将一个定义包含到多个编译单元中,因此编译器更容易内联,如果它选择这样做

但这意味着您不必担心所有内容都会被内联。编译器只会内联尽可能多的内容。

【讨论】:

    【解决方案2】:

    以下是一些不这样做的原因:

    • 无封装; “内部”方法对整个程序可见。
    • 命名空间污染(导致命名冲突或程序员错误)
    • 依赖问题;确保以正确的顺序声明所有内容变得更加困难。
    • 编译时间增加

    【讨论】:

    • 1.封装 - 这根本不应该是一个问题。见this part of the C++ faq。 2.要解决这个问题,只需在不同的命名空间中编写代码...
    • @user1071136:我不是在谈论安全性。
    • 哦。然后呢?如果一个方法是private,那么它是否可见并不重要,除非您关心安全性。没有?
    • @user1071136:我说的是呈现一个定义良好的界面,而不是安全性。也许我的意思是“可访问”而不是“可见”。并非所有函数都是成员函数...
    【解决方案3】:

    抛开性能和内联不谈,有些事情你不能只用标头来做,例如类的static 字段。

    也就是说,STL 中的大多数(如果不是全部)仅是标题,Boost 中的大多数也是如此。

    至于内联方法/函数 - 这并不重要。编译器比您更清楚该做什么,并且可能会忽略 inline 关键字(使函数非内联),或者相反,即使函数没有这样声明,也可以内联函数调用。

    【讨论】:

      【解决方案4】:

      如果所有函数都是“内联”的,那么你的二进制文件会更大,这可能会导致性能下降。您应该只内联非常小的且经常调用的函数。

      【讨论】:

      • 你应该让编译器来决定。
      • 编译器的内联优化和inline关键字是有区别的。标记所有函数inline 并不意味着所有函数都会被内联。
      猜你喜欢
      • 2014-05-06
      • 1970-01-01
      • 1970-01-01
      • 2020-12-24
      • 1970-01-01
      • 1970-01-01
      • 2021-02-02
      • 1970-01-01
      • 2014-10-17
      相关资源
      最近更新 更多