gcc のドキュメントには、次の内容が含まれています。
関数がインラインと静的の両方である場合、関数へのすべての呼び出しが呼び出し元に統合され、関数のアドレスが使用されない場合、関数自体のアセンブラー コードが参照されることはありません。この場合、オプション -fkeep-inline-functions を指定しない限り、GCC は実際には関数のアセンブラー コードを出力しません。一部の呼び出しは、さまざまな理由で統合できません (特に、関数の定義に先行する呼び出しは統合できず、定義内の再帰呼び出しも統合できません)。
それは私にはいつもばかげているように思えました -- なぜ現代のコンパイラはそれほど馬鹿げているのでしょうか? 簡単なテストの後、それは真実ではないようです。
テストコード:
static inline int foo();
int bar() {
return foo();
}
int foo() {
return 42;
}
Linux での gcc-4.9.2 の結果には、 のコードが含まれていますが、 のコードは含まれてbar()
いませんfoo()
。foo()
統合されていることがわかります。
bar:
.LFB0:
.cfi_startproc
movl $42, %eax
ret
.cfi_endproc
C++ としてコンパイルすると、名前マングリングを除いて、結果は同じです。
ドキュメントに反して、foo()
の呼び出し後に定義されているにもかかわらずbar()
、foo()
は完全に に統合されていbar()
ます。
ドキュメントを誤解していますか、それとも間違っていますか? おそらく、より複雑なケースでは正しいでしょうか?
「統合」と「インライン」の間に技術的な違いがあるかどうかはわかりませんが、「統合」はキーワードinline
と区別するために使用されており、関数のインライン化を指しているだけだと思います(したがって、タイトル)。
この質問は C および C++ としてタグ付けされています。これは、gcc ドキュメントのこの部分が「C 言語ファミリー」に関連しており、回答が 2 つの言語で同じであると予想されるためです。