有这样的代码:
int fun1(){
return 2 + 3;
}
inline int fun2(){
return 4 + 5;
}
int main(){
int a = fun1();
int b = fun2();
return 0;
}
和相应的汇编代码:
.file "prog47.cpp"
.text
.globl _Z4fun1v
.type _Z4fun1v, @function
_Z4fun1v:
.LFB0:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
movl $5, %eax
popl %ebp
ret
.cfi_endproc
.LFE0:
.size _Z4fun1v, .-_Z4fun1v
.section .text._Z4fun2v,"axG",@progbits,_Z4fun2v,comdat
.weak _Z4fun2v
.type _Z4fun2v, @function
_Z4fun2v:
.LFB1:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
movl $9, %eax
popl %ebp
ret
.cfi_endproc
.LFE1:
.size _Z4fun2v, .-_Z4fun2v
.text
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
andl $-16, %esp
subl $16, %esp
call _Z4fun1v
movl %eax, 12(%esp)
call _Z4fun2v # why fun2 is called?
movl %eax, 8(%esp)
movl $0, %eax
leave
ret
.cfi_endproc
.LFE2:
.size main, .-main
.section .note.GNU-stack,"",@progbits
为什么函数fun2没有内联并且像普通函数一样被调用?我已经读过内联关键字只是提示编译器,它不需要内联函数,但是fun2的定义非常简单,因此可以内联。如何强制g ++内联函数?
答案 0 :(得分:13)
启用优化功能。这是您使用main
(x86_64)-O2
函数获得的内容:
0000000000400560 <main>:
400560: 31 c0 xor %eax,%eax
400562: c3 retq
它不仅是内联的,而且已被删除。
没有优化,编译器内联的可能性要小得多。 (内联使代码更难调试,因此只使用非常适度的内联级别和默认的非优化选项是个好主意。)
答案 1 :(得分:6)
GCC有一个强制内联的属性:always_inline
inline int fun2() __attribute__((always_inline));
inline int fun2() {
return 4 + 5;
}
将使其适用于任何优化设置。
答案 2 :(得分:5)
inline
是compiler hint。编译器可能实际内联您的代码。