但由於inline跟extern inline的用法在GCC跟C99中幾乎相反,為了相容性,必需得有一種通用的寫法(下面會提到)。而static inline就沒有什麼問題。
已經有人把所有的差異點寫的很清楚了https://read01.com/zh-tw/3APOEG.html#.WbEKVNDTSUk,所以直接下結論。
註:inline只是建議編譯器要做行內編譯,實際上編譯器不一定會執行。通常要 -O1 以上才有效果。
static inline:
- 因為有static,所以很好理解,就是只在單一文件可見。如果要大家都可以共用,就只能放在h檔中了。這也是最通用的做法。
- 效果就是除非無法做行內編譯(例如:遞迴函式或是會用這個函式的指標),不然就不會產生獨立的程式碼。
- 實驗用程式:
- #include <stdio.h>
static inline void ttt() { return; } int main() { ttt(); return 0; }
- 用objdump看一下,會發現只有main,ttt這個函式不會產生獨立的程式碼。
00000000004004b0 <frame_dummy>:
4004b0: bf 20 0e 60 00 mov $0x600e20,%edi
4004b5: 48 83 3f 00 cmpq $0x0,(%rdi)
4004b9: 75 05 jne 4004c0 <frame_dummy+0x10>
4004bb: eb 93 jmp 400450 <register_tm_clones>
4004bd: 0f 1f 00 nopl (%rax)
4004c0: b8 00 00 00 00 mov $0x0,%eax
4004c5: 48 85 c0 test %rax,%rax
4004c8: 74 f1 je 4004bb <frame_dummy+0xb>
4004ca: 55 push %rbp
4004cb: 48 89 e5 mov %rsp,%rbp
4004ce: ff d0 callq *%rax
4004d0: 5d pop %rbp
4004d1: e9 7a ff ff ff jmpq 400450 <register_tm_clones>
00000000004004d6 <main>:
4004d6: b8 00 00 00 00 mov $0x0,%eax
4004db: c3 retq
4004dc: 0f 1f 40 00 nopl 0x0(%rax)
00000000004004e0 <__libc_csu_init>:
4004e0: 41 57 push %r15
4004e2: 41 56 push %r14
inline & extern inline
- 由於效果在GCC跟C99中幾乎相反,推薦以下寫法,編譯的結果才不會不一致。
- 效果會是:函式所在的C檔中,會執行行內編譯。其他C檔中,會被視為一般的函式,所以為了讓其他的C檔連結到,一定會產生獨立的程式碼。
- 實驗用程式(推薦的寫法),需要留意的是,extern後面不可以加inline:
- #include <stdio.h>
extern void ttt(void); inline void ttt() { return; } int main() { ttt(); return 0; }
- 用objdump看一下,會發現ttt這個函式會產生獨立的程式碼,但是main仍然是以行內編譯的方式編譯ttt()。
4004ce: ff d0 callq *%rax
4004d0: 5d pop %rbp
4004d1: e9 7a ff ff ff jmpq 400450 <register_tm_clones>
00000000004004d6 <ttt>:
4004d6: f3 c3 repz retq
00000000004004d8 <main>:
4004d8: b8 00 00 00 00 mov $0x0,%eax
4004dd: c3 retq
4004de: 66 90 xchg %ax,%ax
00000000004004e0 <__libc_csu_init>:
4004e0: 41 57 push %r15
4004e2: 41 56 push %r14
沒有留言:
張貼留言