【发布时间】:2015-06-13 22:23:39
【问题描述】:
当我使用关键字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 或其他编译器如何知道何时内联函数更好?
【问题讨论】:
-
你不应该在意。优化编译器在内联决策方面比你更聪明。
-
inline是一个经常被忽略的提示(尽管您通常可以使用编译器选项强制它返回),编译器在绝大多数情况下更清楚如何内联。该关键字还有一些其他用途,但实际上并非如此。 Related. -
在 Debian/Sid/x86-64 和 GCC 4.9.2 上调用
g++ -fverbose-asm -std=c++14 -O3 -S e.cc编译器 is 内联您的第一个示例并且main变为空 -.e.g.像return 0;一样编译(因为没有明显的副作用) -
另外,请注意:有时使用 inline 关键字会降低性能。有很多关于内联的信息,但并非所有信息都是准确的,仅仅是因为它的使用在很大程度上取决于情况的细节。一些简单的阅读:isocpp.org/wiki/faq/inline-functions#inline-and-perf
-
@SamuelMS:可悲的是,该常见问题解答完全忽略了
inline作为关键字在现代和时代中实际上没有影响一个功能是否应该是内联。 (因此,我希望几乎永远不会使用它来“降低性能”)。
标签: c++ gcc clang compiler-optimization