Mar*_*tin 20 c++ compiler-construction inline
我知道该关键字inline
具有有用的属性,例如用于在头文件中保留模板特化.另一方面,我经常读到这inline
几乎没有用作编译器实际内联函数的提示.此外,关键字不能在cpp文件中使用,因为编译器想要inline
在调用时检查用关键字标记的函数.
因此,我对现代编译器的"自动"内联功能(即gcc 4.43)感到有些困惑.当我在cpp中定义一个函数时,编译器是否可以内联它,如果它认为内联对函数有意义,或者我是否剥夺了他的某些优化功能?(这对于大多数功能来说都没问题,但对于经常调用的小功能很重要)
Mar*_*ork 19
在编译单元内,编译器内联函数没有问题(即使它们没有标记为内联).在编译单元中,它更难,但现代编译器可以做到这一点.
使用inline tag
它对"现代"编译器几乎没有影响,是否实际内联函数(它具有比人类思维更好的启发式)(除非你指定标志强制它的方式或另一种(这通常是一个坏主意,因为人类是不好做出这个决定)).
Cyg*_*gon 18
至少从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个汇编指令,变得膨胀成千字节(!)的嵌套函数调用.在其他时候,它如此积极地内联,即使它们包含非平凡的功能,整个类也会消失.
该标准规定一无所知的功能如何可以被内联.如果编译器可以访问其实现,则可以内联函数.如果你只有一个包含二进制文件的标题,那就不可能了.如果它在同一个模块中,编译器可以内联函数,即使它在cpp
文件中.
归档时间: |
|
查看次数: |
7371 次 |
最近记录: |