2011-09-29 16 views
6

可能性の重複:
What is the difference between r-value references and l-value references? (CodeGen)C++:技術レベル(ASM)のR値参照とは何ですか?

私が思っていた、誰もがR-値の参照は技術的なレベルであるかを説明することができますか?つまり、R-Valueの参照が作成されたときに、アセンブラレベルではどうなりますか。私はそれが「C」にR-値の参照を作成しても意味がありませんが、知っているだけのために

char c = 255; 
char &c2 = c; 
char &c3 = std::move(c); 

:私は、次のコードを書いたの内側に何が起こるかを見るために小さなテストのために

テスト私はとにかく、それが何かを見るためにそれをやった。そして、ここでの結果です:

unsigned char c = 255; 
    mov   byte ptr [c],0FFh 
unsigned char &c2 = c; 
    lea   eax,[c] 
    mov   dword ptr [c2],eax 
unsigned char &&c3 = std::move(c); 
    lea   eax,[c] 
    push  eax 
    call  std::move<unsigned char &> (0ED1235h) 
    add   esp,4 
    mov   dword ptr [c3],eax 

私はこれまでありませんASMの専門家によってだが、それはこの場合には、「C3」は最終的に「C」を定期的に参照され、ように私には見えます。

私は一時的な(文字& & C3 = 255)、などのアセンブラの変更の最後のビットに直接R-値の参照をバインドする場合:この変更のルックスから

unsigned char &&c3 = 255; 
    mov   byte ptr [ebp-29h],0FFh 
    lea   eax,[ebp-29h] 
    mov   dword ptr [c3],eax 

、私は仮定c3は実際には値255を保持するメモリ位置への参照です。したがって、これは通常の参照です。値はc3にコピー/割り当てされません。これは本当ですか?

私の前提が正しいか、トラックから完全に外れていれば誰でも言うことができますか?これまで、R-Valueの参照は、呼び出し元の解像度に関する関数/メソッドのシグネチャ(おそらくmove-ctor)と一致するように考えられていたため、コーダは、提供されたデータをどのように扱うかを知っていますデータをコピーするのではなく、データを移動することになります)。

私はちょうど提示しました:私はレベルで私のコードでぶち壊すつもりはない、私はちょうど周りにあった残りの部分これらすべての年。

洞察と説明は歓迎すべきものではありません。

ありがとうございます!

+3

(最適化されていない)アセンブリレベルでは、R値は、L値、参照、または「値」のように、オブジェクトのインスタンスです。 R値は、コピー/構築に使用する_compiler_関数を単に伝えます。これは、オブジェクトまたはパラメータ内の参照が、実際にはアセンブリレベルでのポインタにすぎず、コンパイラによって別の方法で扱われる方法と似ています。 –

+1

'c3'はr値ではなくl値のリファレンスであることに注意してください。 – avakar

+3

「技術」あなたはその言葉を使い続けます。私はそれがあなたが意味すると思うことを意味するとは思わない。 –

答えて

8

R値の参照が作成されたときのアセンブラレベルはどうなりますか?

高水準セマンティクスを保持するために必要なものは何でも。どんなコンパイラがコンパイラベンダーが良いアイデアだろうと思ったかに依存します。アセンブリには、左辺値、右辺値、または参照の概念がないので、それらを探してはいけません。最適化をオンにすると、あなたが見ているコードがおそらく変更されます(変数が使用されていない場合は、既存のコードがまったく停止する可能性があります)。

私は、これらの年の間にあった残りの部分と比較して、R-Valueの参考文献が導入した技術的な違いを明確にしたいだけです。

リバース参照によって、移動セマンティクスが有効になり、重要な最適化の機会が有効になります。標準では「ああ、これは評価値で、アセンブリで実装する必要があります」とは言いません。実装はアセンブリーをまったく生成しないかもしれません。

4

最適化する前に、参照はバインドされたオブジェクトのアドレスを含むポインタとして存在します。

コンパイラは、最適化を非常に難しくしています。インライン化は、特に、小さな関数内の参照パラメータのすべての使用を、バインドされたオブジェクトの値を含むレジスタの直接使用によって置き換える可能性があります。

6

小数点以下の桁数は、レベルによって異なります(通常の桁数とまったく同じですが(コンパイラの見方によって異なります)。違いはC++言語レベルにのみ存在します。 r値参照は、参照されるオブジェクトが一時的なものであり、それを受け取る者は自由に変更することができます。オブジェクトの場所に関する情報は、通常の参照とまったく同じに転送される可能性があります(コンパイラは異なる方法で最適化しようとしますが、それはコンパイラの内部的な問題です)。

r値参照と非const値参照の違いは、すべてのl値が自動的にl値参照にのみキャストされる(誤った変更を防ぐ)ことで、r値の式は移動セマンティクスがサポートされていない場合は、移動セマンティクスと通常コールを許可して、両方に変換します(r値ref。preffered)。 std :: moveは、l値のr値参照への非自動キャストを許可する以外には何もしません。

0

レファレンスコンセプトは完全にC++レベルで記述することができますが、このためにアセンブリコードを読む必要はありません。内部リソースを割り当てる最小限のC++クラスを取得するだけで、別のオブジェクトによって参照値リソースを「盗む」ことは明らかです。この古典的な記事のremote_integerクラスのように:http://blogs.msdn.com/b/vcblog/archive/2009/02/03/rvalue-references-c-0x-features-in-vc10-part-2.aspx このコードのアセンブリ翻訳はかなり簡単ですが、その違いはC++コードで見られます。 charのような単純な型については、いくつかのrvalue参照構文機能をデモストレーションすることができますが、C++やアセンブリレベルの両方でそのような型の右辺値参照を使用する意味はありません。したがって、C++でchar & & cを使用する利点がない場合は、アセンブリでも面白いことはありません。

関連する問題