c++ - 什么时候可以/将在 C++ 中内联一个函数?可以强制执行内联行为吗?

标签 c++ gcc clang compiler-optimization

我试图在使用关键字 inline 时获得预期的行为。 我尝试在不同的文件中调用函数、模板化函数、使用内联函数的不同实现,但无论我做什么,编译器都不会内联函数。

那么编译器究竟会在哪种情况下选择内联 C++ 中的函数?

这是我试过的代码:

inline auto Add(int i) -> int {
  return i+1;
}

int main() {  
  Add(1);  
  return 0;
}

在这种情况下,我得到:

Add(int):
    pushq   %rbp
    movq    %rsp, %rbp
    movl    %edi, -4(%rbp)
    movl    -4(%rbp), %eax
    addl    $1, %eax
    popq    %rbp
    ret
main:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    $1, %edi
    call    Add(int)
    movl    $0, %eax
    popq    %rbp
    ret

或者再次,

template<typename T>
inline auto Add(const T &i) -> decltype(i+1) {
  return i+1;
}

int main() {  
  Add(1);  
  return 0;
}

我得到了:

main:
    pushq   %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    movl    $1, -4(%rbp)
    leaq    -4(%rbp), %rax
    movq    %rax, %rdi
    call    decltype ({parm#1}+(1)) Add<int>(int const&)
    movl    $0, %eax
    leave
    ret
decltype ({parm#1}+(1)) Add<int>(int const&):
    pushq   %rbp
    movq    %rsp, %rbp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rax
    movl    (%rax), %eax
    addl    $1, %eax
    popq    %rbp
    ret

我用了https://gcc.godbolt.org/在这里获取汇编代码,但我也在我的机器上尝试了 clang 和 gcc(有和没有优化选项)。

编辑:

好的,我遗漏了一些优化选项。如果我将 GCC 设置为使用 o3 优化级别,我的方法是 inlined .

但还是。 GCC 或其他编译器如何知道何时最好内联函数?

最佳答案

通常,您的代码总是仅在您指定时内联:

__attribute__((always_inline))

例如(来自 gcc 文档):

inline void foo (const char) __attribute__((always_inline));

尽管强制编译器内联代码几乎不是一个好主意。

您可以设置高优化级别(通过 O 标志)以实现最大内联,但有关更多详细信息,请参阅 gcc documentation

内联实际上是由许多参数控制的。您可以使用 -finline-* 选项设置它们。你可以看看他们here

关于c++ - 什么时候可以/将在 C++ 中内联一个函数?可以强制执行内联行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30824157/

相关文章:

c++ - 在Qt QGraphicsItem中实现OpenGL推荐

c++ - 将数组的内容复制到 C++ 中调整大小的数组

c++ - 如何使派生构造函数将串联值传递给其父构造函数?

c - GCC 和 CLang 无法识别 Unicode 字符串

c# - 带有简单 DLL 的 SEHException

c - 使用 gcc,我无法获得第 3 方库 Cairo 来链接/编译

c - 仅针对一个 header 禁用#warning

c++ - 减少g++ RAM使用

c++ - Clang 无法从基类中找到 const 模板成员函数

c++ - 为什么 GCC 在 Clang 不使用它的地方插入 mfence?