编译器或链接器的内联函数的区别?

时间:2011-05-10 10:31:38

标签: c++ compiler-construction linker inline

我想知道链接器级别或编译器级别的内联函数在执行速度方面是否有任何区别?

e.g。如果我在.cpp文件中拥有所有函数并依赖链接器进行内联,那么这个内联可能会比在编译器级别选择内联的头文件中定义一些函数或者没有任何链接和所有内联的统一构建更低效由编译器完成?

如果链接器效率很高,为什么还要在编译器级别显式地内联函数呢?这只是为了方便,说只有一行构造函数,因此不能用.cpp文件打扰?

我想这可能取决于编译器,在这种情况下,我最感兴趣的是Visual C ++(Windows)和gcc(Linux)。

由于

4 个答案:

答案 0 :(得分:3)

一般规则是所有其他条件相同,越接近执行(编译 - >连接 - >(可能是JIT) - >执行)优化完成优化器具有的数据越多,优化程度越高。因此,除非优化器是哑的,否则当链接器完成内联时,你应该期望更好的结果 - 链接器将know more about the invokation context并且做更好的优化。

答案 1 :(得分:3)

通常,在链接器运行时,您的源代码已经编译成机器代码。链接器的工作是将所有代码片段和链接连接在一起(可能在整个过程中修复地址)。在这种情况下,没有进行内联的空间。

但并非一切都没有丢失。在编译和链接时,Gcc确实提供了一种链接时间优化机制(使用-flto)选项。这会导致gcc生成一个字节代码,然后链接器可以将其编译并链接到单个可执行文件中。由于字节代码包含的信息多于优化的机器代码。链接器现在可以在整个代码库上执行基本优化。编译器无法做的事情。

有关gcc的更多详细信息,请参阅here。但不确定VC ++。

答案 2 :(得分:1)

内联通常在单个翻译单元(.cpp文件)中执行。当你在另一个文件中调用函数时,它们永远不会内联。

链接时间优化(LTO)对此进​​行更改,允许内联在翻译单元中工作。在生成代码的效率方面,常规链接应始终相同或更好(有时非常非常显着)。

两个选项仍然可用的原因是LTO可以占用大量的RAM和CPU - 我之前已经有VC ++花了几分钟时间来连接一个大的C ++项目。有时在你发货之前启用它是不值得的。你也可能用尽足够大的项目耗尽地址空间,因为它必须将所有字节码加载到RAM中。

为了编写有效的代码,没有任何改变 - 所有相同的规则都适用于LTO。在头文件中明确定义内联函数与依赖于内联函数的LTO相比,它可能更有效。 inline关键字只提供一个提示,因此无法保证,但它可能会将其推送到内联(通常有或没有LTO)的内联中。

答案 3 :(得分:0)

如果函数 内联,则没有区别。

我认为在标题中定义内联函数的主要原因是历史。另一个是便携性。直到最近,大多数编译器都没有进行链接时代码生成,因此在头文件中具有函数是必要的。这当然会影响几年前开始的代码库。

另外,如果你仍然针对一些不支持链接时间代码生成的编译器,你就没有选择。

顺便说一句,我在一个案例中被迫添加一个pragma来询问一个特定的编译器来内联一个.cpp文件中定义的init()函数,但可能会从地方。