2011-10-23 51 views
3

有這樣的代碼:克++不內聯函數

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不內聯和稱爲像正常功能?我已經讀過,inline關鍵字只是提示編譯器,它不需要內聯函數,但fun2的定義非常簡單,所以它可以內聯。如何強制g ++內聯函數?

+0

[你確定你需要的功能是內聯嗎?或者這個問題是出於興趣?] – marnir

+3

所有的代碼應該簡單地消失,因爲它沒有任何有用的副作用。不要忘記啓用優化器。 –

+1

打開一些優化並將內聯函數聲明爲靜態將是一個好的開始。 – cyco130

回答

7

GCC具有強制內聯一個屬性:always_inline

inline int fun2() __attribute__((always_inline)); 
inline int fun2() { 
    return 4 + 5; 
} 

威爾導致它在任何優化設置上工作。

+5

我會說永遠不要強制編譯器內聯。在決定內聯時,編譯器總是比人類做得更好。一個更簡單的想法就是**打開將進行內聯的優化。 –

+0

我也建議不要強制編譯器內聯。但我不同意編譯器總是會比人類做得更好。有時候人類會贏,而那種會贏的人也是那種知道什麼時候忽視這個建議的人。對於我們其他人,請相信編譯器:) – ObscureRobot

+0

@LokiAstari有幾種情況應該強制內聯。它在調試時非常有用,而且在用於別名函數時也非常有用。除類型安全外,其功能與宏相同。 – Pubby

12

打開優化。這就是你爲main函數-O2下(x86_64):

0000000000400560 <main>: 
    400560: 31 c0     xor %eax,%eax 
    400562: c3      retq 

它不僅內嵌,它的去除。

沒有優化,編譯器不太可能內聯。 (內聯使代碼更難調試,所以只有用內聯的非常溫和的水平默認的非優化的選項是一個好主意。)