私の関数をインラインにするかどうかにかかわらず、コンパイラはすべてこのキーワードを完全に使用することを止めることができます(それはとにかくすべてをインラインで実行すると仮定して)。"インライン"の使用を中止できますか?
答えて
inline
の使用を中止することができます。
inline
は、基本的には、ODR (One Definition Rule)を適用しない場合にのみ有効です。要するに、あなたはinline
としての機能をマークすることができますし、この不満リンカずに、複数の翻訳単位で輸入された1つのヘッダファイルに直接彼らの定義を提供:
foo.hpp
inline int foo() { return 42; }
foo.cpp
#include "foo.hpp" // <== THE LINKER WOULD COMPLAIN IF foo() WERE NOT inline,
// because its definition is imported also in main.cpp
void bar()
{
int x = foo();
}
main.cppに
#include "foo.hpp" // <== THE LINKER WOULD COMPLAIN IF foo() WERE NOT inline,
// because its definition is imported also in foo.cpp
int main()
{
std::cout << foo();
}
(、再び、コンパイラがインライン展開を実行することを保証するものではありません)inline
キーワードの存在は、リンカがそれらの定義をマージするようになります。もちろん
、このマージ操作は意味のあるものにするためには、いくつかの異なる翻訳単位の一部になってしまうinline
としてマークされた機能のすべての定義が同じでなければなりません。これが当てはまらない場合は、プログラムに未定義の動作があり、診断は不要です。つまり、コンパイラ/リンカはこの不一致を検出する必要はなく、何かが間違っていると伝えます。
すべてのプログラムがその中に をODR-使用されているすべての非インライン関数や変数の正確に一つの定義が含まれていなければならない。実際にはC++ 11標準のパラグラフ3.2/4パー
プログラム;診断不要。定義はプログラム内で明示的に現れることができ、標準またはユーザ定義のライブラリに があるか、または必要に応じて暗黙的に定義されます(12.1,12.4および 12.8を参照)。インライン関数は、それがodr使用されるすべての翻訳単位で定義されなければならない。あなたは文字通り
inline
としてマークされた同等の機能を有することができることを
通知は、異なる翻訳単位で2回を定義し、それは限り、それらの定義が同一であるとして罰金です:
foo.cpp
inline int foo() // Has the same body in main.cpp, no problem!
{
return 42;
}
メイン。
inline int foo() // Has the same body in foo.cpp, no problem!
{
return 42;
}
int main()
{
std::cout << foo();
}
CPPはしかし、二つの定義が異なる場合は、次の例のように、あなたのコードでUBを注入します:
foo.cpp
inline int foo()
{
return 42; // <== WATCH OUT! Different body in main.cpp
}
メイン。 cpp
inline int foo()
{
return -42; // <== WATCH OUT! Different body in foo.cpp
}
int main()
{
std::cout << foo();
}
これは、一般的に#include
dヘッダーファイルに定義を直接入力すると、関数をinline
とマークする理由です。
また、クラス定義で定義が直接インライン化されているクラスメンバ関数は、自動的にinline
とマークされています。
inline
の用途に応じて異なります。
コモン(MIS) 概念:
inline
だけコンパイラは、またはそれに従わなくてもよい提案です。とにかに、良いコンパイラは何をする必要があるのでしょう。
一方、真実:
inline
通常コールの時点で、関数本体のインライン置換は、通常の関数呼び出し機構に好ましいことであること実装に示します。実装時に、このインライン置換をコール時に実行する必要はありません。 inline
の置換が省略されても、inline
の他の規則(特にw.r.t One Definition Rule)に従います。使用方法のあなたの目的は、最適化ある場合
だから答えは:
YES、あなたが
inline
の使用を停止することができます。現代のコンパイラのほとんどはあなたのためにそれをかなりうまく行います。
しかしinline
の使用方法のあなたの目的は、あなたが答える一つの定義ルールを乗り越えるとODRを壊すことなく、ヘッダーファイル内の関数本体を定義することができるようになる場合は、次のとおりです。
NO ODRをバイパスできるように、関数を明示的に
inline
とマークする必要があります。
注:クラス本体内に定義されたメンバ関数は、暗黙的にinline
ですが、無料の機能には適用されません同じ。
- 1. PDFを作成中にmPdfでインラインCSSを使用できますか?
- 2. Django-インライン関数を使用するとプロセスが中止されました
- 3. アンダースコアテンプレートのインラインJavaScriptでオブジェクトを使用できますか?
- 4. vue.jsを使用している間にインラインsvgの中に<style>を使用できますか?
- 5. React.js - ReactDOM.renderまたはインラインで使用できますか?
- 6. Java(JIT)インライン再帰メソッドを使用できますか?
- 7. どのスレッドタイプを使用するのが適切な停止/中止ですか?
- 8. CORSの使用中にCSRFを防止しますか?
- 9. スクロールアニメーション(jQuery.appear.js)中のスクロールトリガーを禁止しますか?使用
- 10. traitメソッド宣言と実装の両方で#[インライン]を使用できますか?
- 11. ミッドタスクのエラーを中止できますか?
- 12. 関数ポインタで使用される関数をインライン化できますか?
- 13. アプリケーションの一時停止にapplicationWillResignActiveを使用できますか?
- 14. ディスパッチされたアクションからサンクを中止できますか?
- 15. リストアDBを中止できません
- 16. CSSトランジションをインラインで適用できますか?
- 17. Javabeansを休止状態で使用できますか?
- 18. 同期XmlHttpRequestを中止することはできますか?
- 19. 関数からインラインでスタイルを条件付きで適用できますか?
- 20. 実行中のすべてのjavascript関数(インライン)を停止する方法
- 21. INSERT値の中でSELECT文を使用できますか?
- 22. [STAThread] mainの中でスレッドを使用できますか?
- 23. CASE文の中でWITH句を使用できますか?
- 24. pugファイルの中でPHPを使用できますか?
- 25. INSERT文の中でサブクエリを使用できますか?
- 26. 入力文の中で変数を使用できますか?
- 27. ルックバックヒント式の中で量子を使用できますか?
- 28. Laravel Bladeの使用を中止し、Angular JまたはNode Jを使用するのはなぜですか?
- 29. Log4netはカスタムレンダラーの使用を中止します
- 30. 使用インラインは
'' inline'を使用しない場合でも、暗黙的に使用することができます: 'struct Foo {int x; foo():x(0){}}; 'は1つの.cppファイル内にあり、' struct Foo {double d;別の.cppファイルに 'Foo():d(0){}};'を入れ、 'Foo :: Foo'という2つの' inline'コンストラクタを暗黙的に作成しました。 – Yakk
@ヤク:次に、あなたのプログラムは、 'Foo'が匿名の名前空間で宣言されていない限り、未定義の動作をします。 @MatthieuM。 –
うん、私はそれが生産コードで起こっているのを見た。基本的には、「インライン」を使用しなくても、それに噛まれることができるので、インラインが本当に何であるかを理解する必要があります。 – Yakk