gpt4 book ai didi

C++ `inline` 关键字和编译器优化

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:37:05 28 4
gpt4 key购买 nike

我一直听说 inline 关键字不再用作现代编译器的提示,而是用于避免多源项目中的多重定义错误。

但是今天遇到了编译器服从关键字的例子。

没有inline关键字,如下代码

#include <iostream>

using namespace std;

void func(const int x){
if(x > 3)
cout << "HAHA\n";
else
cout << "KKK\n";
}

int main(){
func(5);
}

使用命令g++ -O3 -S a.cpp,生成func未内联的汇编代码。

但是,如果我在 func 的定义前添加 inline 关键字,func 将被内联到 main 中。

生成的汇编代码部分为

.LC0:
.string "HAHA\n"
.LC1:
.string "KKK\n"
.text
.p2align 4,,15
.globl _Z4funci
.type _Z4funci, @function
_Z4funci:
.LFB975:
.cfi_startproc
cmpl $3, %edi
jg .L6
movl $4, %edx
movl $.LC1, %esi
movl $_ZSt4cout, %edi
jmp _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
.p2align 4,,10
.p2align 3

main:
.LFB976:
.cfi_startproc
subq $8, %rsp
.cfi_def_cfa_offset 16
movl $5, %edi
call _Z4funci
xorl %eax, %eax
addq $8, %rsp
.cfi_def_cfa_offset 8
ret
.cfi_endproc

我的编译器是 gcc 4.8.1/x86-64。

我怀疑该函数可以在链接过程中内联,但我不确定是否会发生,如果是这样,我怎么知道?

我的问题是为什么这个代码片段似乎与现代指南相矛盾,例如 When should I write the keyword 'inline' for a function/method?

最佳答案

inline 关键字有几个作用。其中之一是向编译器提示您希望内联该函数 - 但是,这并不意味着编译器必须内联它 [几个编译器中有一个扩展说“无论如何内联它,如果有的话”可能”,例如 MS 的 __forceinline 和 gcc 的 __attribute__(always_inline) ]。

如果函数是内联的,inline 关键字还允许您拥有同名函数的多个实例,而不会出现“同一函数的多个定义”的错误。 [但函数每次必须是相同的来源]。

在这种情况下,我有点惊讶地看到编译器没有内联 func 。但是,将 static 添加到 func 也会使其内联。很明显,编译器是基于“其他一些函数也可能正在使用 func,所以我们无论如何都需要一个拷贝,并且内联它没有太多好处。事实上,如果你将函数设为静态,并且它只被调用一次,即使函数非常大,gcc/g++ 几乎肯定会内联它。

如果你想让编译器内联一些东西,添加 inline 也没什么坏处。然而,在许多情况下,编译器会做出合适的选择。例如,如果我将代码更改为:

const char* func(const int x){
if(x > 3)
return "HAHA\n";
else
return "KKK\n";
}

int main(){
cout << func(5);
}

它确实内联了 return "HAHA\n"; 左边的 func 部分。

编译器决定内联或不内联的逻辑很复杂,其中一部分是“我们获得了多少,与它占用了多少代码空间”——调用 operator<<(ostream& ,const char *) 的开销很可能是在这种情况下,对于内衬来说太多了。不幸的是,并不总是容易理解为什么编译器会做出某个决定......

关于C++ `inline` 关键字和编译器优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18932237/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com