2017-09-22 12 views
-2

なし静的メンバー関数は暗黙的にポインタthisを持っています。だから、これらのインライン関数はクラス外で呼び出されたときにコンパイラに置き換えられません。これは、クラスインライン関数の使用が非常に制限されているようです!クラスインライン関数が呼び出されたときにコンパイラは実際に何をしますか?

+0

Cにはクラスがないため、これは成果物です。私は、しかし、あなたは明らかに、コードサンプルとおそらく質問の意味を理解することはできません? – Quentin

+2

暗黙の 'this'引数を持つことがインライン展開と関係していると思われるのはなぜですか? – HolyBlackCat

+2

コンパイラは、情報が正しく渡され、必要に応じてコードが動作することを保証する限り、必要な機能をインライン化できます。ただし、コンパイラはコンパイラによって異なります。 – Peter

答えて

2

最適化コンパイラは、希望に応じてinlineとすることができます。

たとえば、あなたはコンパイルかもしれないとリンクg++ -flto -O2(リンク時、プログラム全体optimization option ... GCCの)と、プログラム全体。

(警告:大幅ビルド処理が遅くなりg++ -flto -O2を使用して、基本的にすべてがほぼ「二回」にコンパイルされ、一回一回GIMPLE表現が再最適化されます「リンク」の時間、で、時間を「コンパイル」で)

あなたは、どのような関数呼び出しがインラインになるか(多くは可能性があります)に驚いています。これは、静的な機能とは関係なく、マークされているかどうかはinlineです。

だから、インライン化についてのケア(それが実装と最適化の詳細である)が、あなたのコンパイラは、良い仕事をすること希望べきではありません。

(時々g++であなたがgdbとデバッグを容易にするために、ほとんどのインライン化を無効にしたい。そして、withg++ -fno-inline -Wall -Wextra -O0 -gをコンパイル)

彼らはクラスの外に呼び出されたときしたがって、これらのインライン関数は、コンパイラによって置き換えられません、私は正しい?あなたは間違っている

thisはちょうど暗黙の引数(もthat参照)、そしてもちろんコンパイラは、多くの場合、メンバ関数への呼び出しをインライン化しています。 の実践コンパイラがその最適化を行わなかった場合(多くのメンバ関数-e.g. gettersとsetters - 非常に短く素早いので)、C++は非効率的になります。

C++は仕様(コンパイラではありません)と書かれています。インライン化は実装上の問題であり、発生する可能性もありません。

コンパイラが実際に何をしているのか気にしていて、気にする必要はありませんが、あなたのコードにundefined behaviorを避ける必要がある場合は、生成されたアセンブラコードを表示してください。 GCCg++ -O2 -fverbose-asm -Sとコンパイルしてfoo.sアセンブラファイルをfoo.cc翻訳単位から取得します。

+0

'-fno-fat-lto-objects'を使うと、ダブルコンパイルを防ぐことができます。 –

+0

しかし、まだLTOのコンパイルは遅いです –

+0

あなたが書いたように2回ではありません。 –

2

インラインメンバ関数が呼び出されると、コンパイラはどの関数呼び出しに対しても何もしません。引数を準備して関数を呼び出します。関数呼び出しはすべてインライン展開の対象です。一部の関数はインライン化できません(e.g. functions using alloca or vararg functions、定義が利用できない関数)が、インライン化を防ぐことはできません。

+1

「一部の関数はインライン化されません」という意味です。非常に巧妙なコンパイラは、理論上は 'alloca'や' va_arg'を使って関数をインライン展開することができます。実際には(GCC)(http://gcc.gnu.org/)はこれを行うことができませんが、たくさんの仕事があれば、あなたが本当にしたいと思うならそれをするかもしれません(例えば、月にGCCプラグインをコード化する) –

+0

@BasileStarynkevitchこれは理論的に可能です。しかし、私はそれが既存の制限のいくつかに言及する価値があると思った。 –

関連する問題