16

我一直在测试 C++ 中的内联函数调用。

Thread model: win32
gcc version 4.3.3 (4.3.3-tdm-1 mingw32)

C++ 编程语言中的 Stroustrup 写道:

inline 说明符是对编译器的提示,它应该尝试生成代码 [...] 内联,而不是为函数放置一次代码,然后通过通常的函数调用机制进行调用。

但是,我发现生成的代码根本不是内联的。isquare函数有一个CALL 指令

替代文字

为什么会这样?那我该如何使用内联函数呢?

编辑:使用的命令行选项:

**** Build of configuration Debug for project InlineCpp ****

**** Internal Builder is used for build               ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -osrc\InlineCpp.o ..\src\InlineCpp.cpp
g++ -oInlineCpp.exe src\InlineCpp.o
4

7 回答 7

48

就像 Michael Kohne 提到的那样, inline 关键字始终是一个提示,对于您的函数,GCC 决定不内联它。

由于您使用的是 Gcc,因此您可以使用 __attribute((always_inline)) 强制内联。

例子:

 /* Prototype.  */
 inline void foo (const char) __attribute__((always_inline));

资料来源:GCC 内联文档

于 2009-06-01T12:06:39.417 回答
23

没有通用的 C++ 方法可以强制编译器创建内联函数。请注意您引用的文本中的“提示”一词-编译器没有义务听您的话。

如果你真的,绝对必须做一些内联的东西,你需要一个编译器特定的关键字,或者你需要使用宏而不是函数。

编辑:njsf 在他的回复中给出了正确的 gcc 关键字。

于 2009-06-01T12:00:05.653 回答
8

您是否正在查看调试版本(已禁用优化)?编译器通常在“调试”构建中禁用内联,因为它们使调试更加困难。

无论如何,inline指定的确实是一个提示。编译器不需要内联函数。任何编译器可能决定忽略内联提示的原因有很多:

  • 编译器可能很简单,并且不支持内联
  • 编译器可能会使用内部算法来决定内联的内容并忽略提示。
    (有时,编译器在选择内联内容方面可能做得比您做得更好,尤其是在像 IA64 这样的复杂架构中)
  • 编译器可能会使用自己的启发式方法来决定尽管有提示,但内联不会提高性能
于 2009-06-01T12:11:35.367 回答
4

内联只不过是对编译器的一个建议,如果可以内联这个函数,那么编译器应该考虑这样做。有些函数会自动内联,因为它们非常简单,而您建议它内联的其他函数不会因为它们太复杂而不会内联。

另外,我注意到您正在进行调试构建。我实际上不知道,但编译器可能会禁用调试构建的内联,因为它使调试器变得困难......

于 2009-06-01T12:44:24.707 回答
3

这是一个提示,编译器可以选择忽略该提示。我想我读到了一些 GCC 通常忽略它的地方。我记得听说有一个标志,但它在 100% 的情况下仍然不起作用。(我还没有找到链接)。

标志:-finline-functions 在 -O3 优化级别打开。

于 2009-06-01T12:04:15.490 回答
0

是否内联取决于编译器。是否可以免费忽略内联提示。一些编译器有一个特定的关键字(如__forceinline在 VC++ 中),但即使有这样一个关键字,对虚拟成员函数的虚拟调用也不会被内联。

于 2009-06-01T12:03:00.280 回答
0

我遇到了类似的问题,发现它只有在将内联函数写入头文件时才有效。

于 2009-06-01T12:50:39.467 回答