繁体   English   中英

现代C ++编译器是否可以内联cpp文件中定义的函数

[英]Can modern C++ compilers inline functions that are defined in a cpp file

我知道关键字inline具有有用的属性,例如用于将模板特化保留在头文件中。 另一方面,我经常读到inline几乎没有用作为编译器实际内联函数的提示。 此外,关键字不能在cpp文件内使用,因为编译器希望在调用它们时检查带有inline关键字标记的函数。

因此,我对现代编译器(即gcc 4.43)的“自动”内联功能有些困惑。 当我在cpp中定义一个函数时,如果编译器认为内联对该函数有意义,或者我会抢夺他一些优化功能,编译器是否可以对其进行内联? (对于大多数功能而言,这是可以的,但对于经常调用的小型功能来说,重要的是要知道)

在编译单元内,编译器将没有问题的内联函数(即使它们未标记为内联)。 跨编译单元很难,但是现代编译器可以做到。

inline tag使用对“现代”编译器以及实际上是否内联函数几乎没有影响(它比人的思维具有更好的启发性)(除非您指定标志以一种方式或另一种方式强制执行(这通常是一个坏主意,因为人类不善于做出这个决定))。

至少从Visual Studio 2005开始,Microsoft Visual C ++才能够这样做。他们将其称为“整个程序优化”或“链接时代码生成”。 在此实现中,编译器实际上不会产生机器代码,而是将预处理的C ++代码写入目标文件。 然后,链接器将所有代码合并为一个巨大的代码单元,并执行实际的编译。

GCC至少从4.5版开始就可以执行此操作,而GCC 4.7则进行了重大改进。 据我所知,该功能仍被认为是试验性的(至少在许多不使用该功能的Linux发行版中)。 GCC的实现方式非常相似,首先将经过预处理的源代码(以其GIMPLE中间语言)写入目标文件,然后将所有目标文件编译为一个目标文件,然后传递给链接器(这使GCC可以继续工作与现有的链接器)。

许多大型C ++项目也都执行所谓的“统一构建”。 不是将数百个单独的C ++源文件传递给编译器,而是创建一个包含项目中所有其他源文件的源文件。 这样做的初衷是为了减少编译时间(因为不必反复分析标头等),但副作用是,其结果与上述LTO / LTCG技术相同:编译器可以完美地查看所有编译单元中的所有功能。


我在C ++编译器(MSVC 2010)的独创性和愚蠢感动之间惊叹不已。 某些通过模板进行像素格式转换的代码在正确内联时可以解析为5-10条汇编指令,但膨胀到千字节(!)的嵌套函数调用中。 在其他时候,它是如此内联,即使它们包含非平凡的功能,整个类也会消失。

这取决于您的编译标志。 使用-combine-fwhole-programgcc可以跨cpp边界内联函数。 我不确定如果编译成多个目标文件,链接器将执行多少操作。

该标准要求一无所知的功能如何被内联。 如果编译器可以访问其实现,则可以内联函数。 如果您只有带有二进制文件的标头,那将是不可能的。 如果在同一模块中,即使它在cpp文件中,编译器也可以内联该函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM