問題タブ [copy-elision]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 次のコードがコピーコンストラクターも呼び出すのはなぜですか?
g_Fun()
実行時にreturn temp
コピーコンストラクターが呼び出されるのはなぜですか?
c++ - コンパイラーは、setterメソッドで移動セマンティクスを自動的に適用しますか?
コンパイラが次のsetterメソッドでwstringのmoveコンストラクタを自動的に使用できるかどうかを知りたい(std :: moveを明示的に呼び出さないで):
私が読んだところによると、strは左辺値であるため、コンパイラーはこの決定を行うことが許可されていないように聞こえますが、ここでmoveを使用してもプログラムの動作は変わらないことは明らかです。
移動を除いて、他の種類のコピーの省略が適用されますか?
c++ - 関数パラメータのコピーの排除
カスタム メモリ アロケータを作成しています。できればこのようなオブジェクト作成機能を作り、作成手順を完全に抽象化したい。
しかし、これはコピーを引き起こします。この場合、コピーを強制的に排除する方法はありますか?
これが私の現在のテストコードです。
value
as T&
, T const&
,T&&
を渡そうとしましたT const&&
が、それでもコピーされます。オプティマイザーが関数フレームを削除すると予想していたので、関数パラメーターを R 値に推定できますが、まだCOPY!
メッセージが表示されます。
C++11のフォワーディングテンプレートも試してみましたが、仮想関数にできないので使えませんでした。
私のコンパイラは、Xcode に含まれている Clang です。(clang-425.0.28) また、最適化レベルは に設定されてい-Os -flto
ます。
更新 (後で参照するため)
追加のテストを作成し、生成された LLVM IR をclang -Os -flto -S -emit-llvm -std=c++11 -stdlib=libc++ main.cpp;
オプションでチェックしました。私が観察できることは次のとおりです。(1)関数フレームは常に削除できます。(2) 大きなオブジェクト (4096 バイト) が値渡しされた場合、削除されませんでした。(3) を使用して r 値参照を渡すstd::move
とうまくいきます。(4) move-constructor を作成しない場合、コンパイラはほとんどの場合 copy-constructor にフォールバックします。
c++ - C++: 呼び出される適切なコンストラクターはどれですか: コンストラクターまたはコピー コンストラクター?
コード
印刷"constructor"
され、それで問題ありません。ここで、コピー コンストラクターのコメントを外すと、コンパイル時エラーが発生します。
これはおそらく、コピー コンストラクターが一時的に呼び出されることを示していますElisionTest(10)
。また、一時的なものへの非 const 参照を持つことはできないため、コピー コンストラクターの引数を a にconst&
することでエラーが解決されるはずです。
しかし、コピー コンストラクターをのconst ElisionTest&
代わりに取得するように変更するElisionTest&
と、エラーは発生せず、出力は"constructor"
再び表示されます。なぜ印刷されなかったの"copy constructor"
ですか?
c++ - RVO と NRVO が標準で義務付けられていないのはなぜですか?
RVO および NRVO の最適化が (適用可能な場合に) 標準で義務付けられていないのはなぜですか? たとえば、関数が何らかのオブジェクトを生成し、それを結果として返すという非常に一般的なケースがあります。コピー/移動コンストラクターは通常、RVO/NRVO のために省略されますが、それでも定義する必要があるため、多少混乱します。RVO/NRVO が標準に含まれていた場合、この場合、コピー/移動コンストラクターは不要になります。
c++ - 値渡しとコピー省略の最適化
https://web.archive.org/web/20120707045924/cpp-next.com/archive/2009/08/want-speed-pass-by-value/に出くわしました
著者のアドバイス:
関数の引数をコピーしないでください。代わりに、それらを値で渡し、コンパイラーにコピーさせます。
ただし、この記事に示されている 2 つの例でどのような利点が得られるかはよくわかりません。
対
どちらの場合も、追加の変数が 1 つ作成されるため、メリットはどこにあるのでしょうか? 私が見る唯一の利点は、一時オブジェクトが2番目の例に渡された場合です。
c++ - 失敗時の RVO 強制コンパイル エラー
ここでは、RVO をいつ実行できるかについて多くの議論が行われていますが、実際にいつ実行されるかについてはあまり議論されていません。何度も述べているように、標準に従って RVO を保証することはできませんが、RVO の最適化が成功するか、対応するコードがコンパイルに失敗することを保証する方法はありますか?
これまでのところ、RVO が失敗したときにコードがリンク エラーを発行するようにすることに部分的に成功しました。このため、コピー コンストラクターを定義せずに宣言します。x(x&&)
明らかに、これは、1 つまたは両方のコピー コンストラクター、つまりとを実装する必要があるまれではないケースでは、堅牢でも実行可能でもありませんx(x const&)
。
これは私の 2 番目の質問につながります。コンパイラの作成者は、ユーザー定義のコピー コンストラクターが存在する場合に RVO を有効にすることを選択し、既定のコピー コンストラクターのみが存在する場合には有効にしないのはなぜですか?
3 番目の質問:プレーン データ構造に対して RVO を有効にする他の方法はありますか?
最後の質問 (約束):私のテスト コードを、gcc と clang で観察した以外の動作にするコンパイラを知っていますか?
問題を示す gcc 4.6、gcc 4.8、clang 3.3 のサンプル コードを次に示します。この動作は、一般的な最適化またはデバッグ設定には依存しません。もちろん、オプション--no-elide-constructors
はそれが言うことを行います。つまり、RVO をオフにします。
出力:
RVO はプレーンなデータ構造でも動作しないようです:
出力:
更新:一部の最適化は RVO と非常に簡単に混同されることに注意してください。のようなコンストラクタ ヘルパーmake_x
がその例です。最適化が実際に標準によって強制されているこの例を参照してください。
c++ - std::ペア移動は定義で省略されていませんか?
Visual Studio 2012 で非常に奇妙なことに気付きました: ペア オブジェクトを次のように定義します。
VC11 のペアのコピー/移動を省略しません。この呼び出しは次のように表示されます。
つまり、一時的なペアが作成され、objp 変数に移動されます。(pair<...> obj;
デフォルトの ctor のみをログに記録すると宣言する)
LogMe テスト オブジェクトだけでクロス チェックしました。
ここで割り当ては省略されます。
IDEOne (gcc 4.8.1 を使用) でテストすると、無関係な移動が常に省略されていることが示されるため、これは VC11 に固有のようです。
何が起きてる? 初期化コピーが省略されていることに頼ることができないことは、私を緊張させます。
注: リリース バージョンとデバッグ バージョンのテストでは、同じ結果が表示されます。(MSVCの最適化フラグとは無関係にコピー省略が実行されるため、これは予想していたでしょう。)
テストする完全なソースコード ( ideone リンクも参照):