[解決済み] インラインの使い道はまだあるのか?重複
質問
私は信じていた。
inline
は時代遅れだと信じていました。
ここで
:
関数をどのように指定しても
inline
として指定された関数を呼び出した場合、コンパイラはその関数を無視してもよいということになります。
inline
.
しかし
について
は私が知らないことを理解しているようだ。で
この質問
について、彼と私はかなり行き来しています。
inline
がまだ有用であるかどうかについて、彼と私はかなり行き違います。
この質問は ではなく に関する質問です。
-
の歴史的な使用は
inline
またはinline
というヒントをコンパイラに与えるために使用されます。inline
関数を使用することができます。 関数/メソッドのキーワード 'inline' はいつ書けばいいのでしょうか? . - 関数コードをインライン化することの利点または欠点。 C++におけるインライン関数の利点?
-
コンパイラに強制的に
inline
関数のコードに変換します。 他の翻訳ユニットでインライン関数を強制する
コンパイラは
inline
を自在に操ることができますので
inline
はそこでは役に立ちません。
どこで
inline
は強制的に使われます。
提案しない
コンパイルされたコードに変更を加えるか?
どのように解決するのですか?
私の「秘密の理解」を、できる限り説明したいと思います。
ここには 2 つの全く別のコンセプトがあります。1 つは、関数本体を呼び出し場所で直接繰り返すことにより、関数呼び出しを置き換えるコンパイラの機能です。もうひとつは、複数の翻訳ユニットで関数を定義する可能性です (= 複数の
.cpp
ファイル) で関数を定義できることです。
1つ目は、関数のインライン化と呼ばれるものです。2つ目は目的の
inline
というキーワードを使うことです。
歴史的に
は
inline
と書かれた関数をインライン化するようにコンパイラに強く要求していました。
inline
. コンパイラの最適化が進むにつれて、この機能は後退していき、現在では
inline
を関数のインライン化の提案として使うことは、本当に時代遅れです。コンパイラは、より良い最適化であると判断した場合、喜んでそれを無視し、完全に別のものをインライン化します。
私たちは明示的な
inline
-インライン化の関係については対処できたでしょうか。現在のコードには何もありません。
では、実際にどのような目的で
inline
キーワードは何のためにあるのでしょうか?それは簡単です。
inline
とマークされた関数は、1 つの定義規則 (ODR) に違反することなく複数の翻訳ユニットで定義することができます。次の 2 つのファイルを想像してみてください。
ファイル1.cpp
int f() { return 42; }
int main()
{ return f(); }
ファイル2.cpp
int f() { return 42; }
このコマンドは
> gcc file1.cpp file2.cpp
リンカーエラーが発生し、シンボル
f
が2回定義されていると文句を言うリンカーエラーが発生します。
しかし、関数をマークする場合は
inline
キーワードでマークすると、コンパイラやリンカに具体的に次のように伝えます: "この関数の複数の同じ定義が
ではなく
エラーにならないようにしてください。
ということで、以下のようにするとうまくいきます。
ファイル1.cpp
inline int f() { return 42; }
int main()
{ return f(); }
ファイル2.cpp
inline int f() { return 42; }
この2つのファイルを一緒にコンパイル・リンクしても、リンカエラーは発生しません。
の定義は、もちろん
f
の定義は、ファイルにそのまま書かれている必要はないことに注意してください。それは
#include
d ヘッダーファイルから来ることができます。
f.hpp
inline int f() { return 42; }
ファイル1.cpp
#include "f.hpp"
int main()
{ return f(); }
ファイル2.cpp
#include "f.hpp"
基本的に、ヘッダファイルに関数の定義を書き込むためには、その関数を
inline
としてマークしなければならず、さもなければ多重定義エラーになります。
パズルの最後のピースは、なぜキーワードの実際のスペルが
inline
と綴られているのでしょうか?理由は簡単で、関数をインライン化する (つまり、呼び出し元で関数の本体を繰り返すことで呼び出しを置き換える) には、コンパイラは
を持つ
を持たなければなりません。
C++は別のコンパイルモデルに従っており、ここでは
コンパイラ
は現在生成しているファイル以外のオブジェクトファイルにアクセスすることができません。したがって、関数をインライン化するためには、その定義が現在の翻訳ユニットの一部でなければなりません。もし、複数の翻訳ユニットでインライン化したいのであれば、その定義はすべての翻訳ユニットに存在しなければなりません。通常、これは多重定義エラーにつながります。ですから、もしあなたが関数をヘッダに置いて
#include
としてマークしなければなりません。
inline
としてマークし、多重定義エラーを防ぐ必要があります。
今日でも、コンパイラは適切と思われる関数をインライン化する一方で、その関数の定義にアクセスしなければならないことに注意してください。そのため
inline
キーワードはヒントとして要求されません。
を有効にする
を有効にする必要があります。また、定義がないと、コンパイラーは単に関数をインライン化することができません。
コンパイラはできません。リンカーは可能です。最新の最適化技術には、リンクタイム コード生成 (別名、プログラム全体の最適化) があり、実際のリンクの前に、リンク プロセスの一部として、すべてのオブジェクト ファイルに対して最適化ツールが実行されます。このステップでは、もちろんすべての関数定義が利用可能であり、インライン化も完全に可能であり、1つも
inline
キーワードを使用することなくインライン化が可能です。しかし、この最適化は一般にビルド時間、特に大規模なプロジェクトではコストがかかります。このことを考慮すると、インライン化のために LTCG のみに依存することは最良の選択とは言えないかもしれません。
完全性のために。最初の部分で少しごまかしました。ODR プロパティは、実際には
inline
キーワードのプロパティではなく
インライン関数
(これは言語の用語です)。インライン関数のルールは
- リンカーエラーを起こすことなく、複数の翻訳ユニットで定義することができる
- 使用されるすべての翻訳ユニットで定義する必要があります。
- すべての定義はトークン対トークン、エンティティ対エンティティの同一でなければなりません。
は
inline
キーワードは関数をインライン関数に変えます。関数をインライン化するもう一つの方法は、クラス定義の中で関数を直接定義する(単に宣言するのではない)ことです。そのような関数は、たとえ
inline
キーワードがなくても自動的にインライン化されます。
関連
-
[解決済み】テンプレートの引数1が無効です(Code::Blocks Win Vista) - テンプレートは使いません。
-
[解決済み] 非常に基本的なC++プログラムの問題 - バイナリ式への無効なオペランド
-
[解決済み] 式はクラス型を持つ必要があります。
-
[解決済み] スマートポインターとは何ですか?
-
[解決済み] 仮想デストラクタはいつ使うのか?
-
[解決済み] 関数/メソッドのキーワード 'inline' はいつ書けばよいのですか?
-
[解決済み】JavaScriptの関数にデフォルトのパラメータ値を設定する
-
[解決済み】高放射能環境下で使用するアプリケーションのコンパイルについて
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
-
[解決済み] インライン仮想関数は本当に無意味なのか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】構造体のベクター初期化について
-
[解決済み】C++でランダムな2倍数を生成する
-
[解決済み】Cygwin Make bash コマンドが見つかりません。
-
[解決済み】指定範囲内の乱数で配列を埋める(C++)
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)
-
[解決済み】VC++の致命的なエラーLNK1168:書き込みのためにfilename.exeを開くことができません。
-
[解決済み】システムが指定されたファイルを見つけられませんでした。
-
[解決済み] 関数/メソッドのキーワード 'inline' はいつ書けばよいのですか?
-
[解決済み】C++のインライン関数の利点は?