我的问题很简单:
我正在研究旧的遗留代码,其中大部分功能仅在头文件中实现。 据我所知,编译器将头文件中实现的函数转换为内联函数。
我想知道我是否将这些实现移动到.cxx文件中,有什么好处?
答案 0 :(得分:3)
对于编译器,来自.cxx文件或.h文件的输入之间没有区别,此文本被编译为相同的翻译单元。
我们通常不将代码置于头文件中的主要原因是避免重复对象,当多个文件被多个文件使用时,这些对象会在链接器级别发生冲突。 cxx文件。
也许你在使用宏来混淆内联函数,因为在宏的情况下,它本质上是一个预处理指令,不存在链接器时间冲突的风险,即使/如果相同的头文件多次被包含在内也是如此不同的翻译单位。
当然可以在标题(或其他地方)中定义函数,以指示编译器系统地内联对函数的调用,并且在这种情况下,链接时也没有冲突。然而,这需要特殊的语法,并且仅仅是因为代码来自包含文件或cpp文件(如问题所示)。
现在,回答这个问题,将所有这些代码从头文件和cpp文件中移出,不应对二进制大小和性能产生太大影响。
显然,如果头文件中的函数定义没有明确地内联,那么每个不同的exe / dll必须只有一个头文件的用户(否则在链接时会有重复),因此文件不会改变在任何一个方向。
关于性能,随着硬件的一般性能提升,即使以前内联的函数现在被正常调用,这应该通常不被注意,在性能方面,可能除了特定的紧密循环,其中逻辑迭代很多次。
答案 1 :(得分:2)
在传统时代,过程调用机器操作相当昂贵,因此C和C ++的宏处理特性以及inline
函数偶尔也很重要。
随着时间的推移,个别机器操作不再是性能问题。
事实上,情况有所改变。将过程扩展为内联代码无处不在,最大限度地减少已经优化的CPU过程调用机器操作,但是通过浪费宝贵的内环缓存空间和相同功能的数十万份副本,确实破坏了缓存。
我说:定义实际功能。 CPU会处理这个问题。
您的应用程序似乎是一个时代的工件,将代码爆炸成直线执行很受欢迎。我认为部分原因可以追溯到最初的VAX 11/780,它是第一个流行的Unix 32位系统,并且在一段时间内定义了1 MIPS CPU,但需要夸大和微编码的calls
指令17美国要执行。是的, 17x 正常操作。这不再是真的,但合理地试图处理VAX奇怪性的BSD编码风格至今仍然存在。 (嘿,我是BSD粉丝,但今天我们不需要宏中的所有内容。)
因此,要回答您的确切问题:通过将这些例程迁移到单独链接的.cxx模块中,您将获得更好的缓存性能。来吧,做吧。
答案 2 :(得分:1)
头文件的目的是包含可能包含在多个源文件中的定义。放置在头文件中的代码#included到源文件中,然后编译。就编译的代码而言,它与该标题的全部内容是源的一部分是一样的。
将代码放在标头或源(cxx)文件中是惯例。编译器不会根据它的位置改变行为。
答案 3 :(得分:0)
您可以在“大规模C ++软件设计”第6章“绝缘”中找到答案
包含的可以更改,添加或删除的实现细节 没有强迫客户重新编译据说是绝缘的。