【发布时间】:2012-07-10 19:48:18
【问题描述】:
我正在维护一个大型模板类库,这些模板类基于float 或double 类型执行代数计算。许多类都有访问器方法(getter 和 setter)和其他运行少量代码的函数,因此当编译器找到它们的定义时,这些函数需要被限定为内联。相比之下,其他成员函数包含复杂的代码,因此最好调用而不是内联。
函数定义的很大一部分位于头文件中,实际上位于头文件所包含的 .inl 文件中。但是也有许多类的函数定义通过显式实例化float 和double 愉快地存在于.cpp 文件中,这对于库来说是件好事(here 解释了原因)。最后,有相当多的类的函数定义在 .inl 文件(访问器方法)和 .cpp 文件(构造函数、析构函数和繁重的计算)中被破坏,这使得它们都很难维护。
只有当我知道一种可靠的方法来防止某些函数被内联时,我才会将我的所有类实现放在 .inl 文件中,或者如果 inline 关键字可以强烈建议编译器内联某些函数,则在 .cpp 文件中,当然,事实并非如此。我真的希望库中的所有函数定义都驻留在 .cpp 文件中,但是由于访问器方法在整个库中被广泛使用,我必须确保它们在被引用时被内联,而不是被调用。
因此,在这方面,我的问题是:
用
inline标记模板函数的定义是否有意义,因为我最近了解到here,它将被自动限定为内联编译器不管它是否标有inline?而且最重要的是,因为我希望将模板类的所有成员函数的定义聚集在一个文件中,要么是.inl 或 .cpp(在 .cpp 的情况下使用显式实例化),最好 仍然 能够提示编译器(MSVC 和 GCC)应该内联哪些函数和 不应该,确定模板函数是否可以做到这一点,我怎样才能做到这一点,或者,如果真的没有办法(我希望有),会是什么最佳折衷方案?
---------
EDIT1:我知道inline 关键字只是对编译器内联函数的建议。
EDIT2:我真的知道。我喜欢向编译器提出建议。
EDIT3:我仍然知道。这不是问题所在。
---------
鉴于一些新的信息,还有第三个问题与第二个问题并驾齐驱。
3. 如果现在编译器非常聪明,他们可以更好地选择应该内联的函数以及应该调用的函数并且能够链接时间代码生成和链接时优化,这有效地允许他们在链接时查看位于 .cpp 的函数定义以决定其被内联或调用的命运,那么也许一个好的解决方案是将所有定义移动到相应的 .cpp文件?
---------
那么结论是什么?
首先,我感谢 Daniel Trebbien 和 Jonathan Wakely 提供的结构化和有理有据的答案。两者都赞成,但只能选择一个。然而,没有一个给出的答案对我来说是一个可以接受的解决方案,所以所选择的答案恰好是比其他人更能帮助我做出最终决定的答案,下面将为感兴趣的人解释其细节。
好吧,由于我一直重视代码的性能而不是维护和开发的便利程度,在我看来,最可接受的折衷方案是移动所有访问器方法和其他轻量级成员函数将每个模板类添加到相应标头包含的 .inl 文件中,用 inline 关键字标记这些函数,以尝试为编译器提供良好的提示(或为内联强制提供关键字),然后移动其余部分的函数到各自的 .cpp 文件中。
将所有成员函数定义都放在 .cpp 文件中会阻碍轻量级函数的内联,同时会引发链接时优化的一些问题,正如 Daniel Trebbien 为 MSVC(在较早的开发阶段)和 Jonathan Wakely 所确定的那样对于 GCC(在其当前的发展阶段)。并且将所有函数定义都放在头文件(或 .inl 文件)中并不会超过将每个类的实现分类到 .inl 和 .cpp 文件中以及该决定的额外副作用的总结好处:它将确保库的客户端只能看到原始访问器方法的代码,而二进制文件中隐藏了更多有趣的东西(确保这不是主要原因,但是对于任何熟悉软件库的人来说,这一点都很明显)。并且任何不需要被库的包含文件公开并由其类私有使用的轻量级成员函数都可以在类的 .cpp 文件中具有其定义,而其声明/定义带有@987654333 @ 鼓励函数的内联状态(还不知道关键字应该在两个地方还是在这种特殊情况下只在一个地方)。
【问题讨论】:
-
简单地搜索“内联”和“模板”似乎已经引起了很多讨论,其中的问题已经敲定。例如:stackoverflow.com/questions/10535667/…
-
@HostileFork 谢谢,但是,它是那些罕见的 SO 页面之一,其中最重要的答案是矛盾的。希望这个话题有另一个机会在这里得到一些共识。
-
..在没有提供任何有价值的信息或分享经验的情况下相互矛盾,真的。
-
我想我很困惑。问题是“束缚我的编译器的内联策略是否有意义?”这是一个关于优化的问题,您需要“可信和/或官方”的回复。我认为对此类问题唯一可能的“可信和/或官方”回答必须是“视情况而定”。
-
@ybungalobill: 链接加速绝对是你通过整体程序优化无法获得的。
标签: c++ templates compiler-construction inline