C ++:什么是技术层面的R值引用(ASM)?

时间:2011-09-29 15:55:54

标签: c++ assembly rvalue-reference

  

可能重复:
  What is the difference between r-value references and l-value references? (CodeGen)

我想知道,任何人都可以在技术层面解释什么是R值参考?我的意思是:当创建R值引用时,汇编程序级别会发生什么。

对于一个小测试,看看里面发生了什么,我写了下面的代码:

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

我知道创建一个对'c'的R值引用是没有意义的,但是为了测试我还是做了它,看看它做了什么。这是结果:

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

到目前为止,我还不是专家,但我认为,在这种情况下,'c3'最后是对'c'的常规引用。

如果我将R值引用直接绑定到临时(char&amp;&amp; c3 = 255),则汇编程序的最后一位会发生变化:

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),因此编码器知道如何处理提供的数据(对于移动者来说)这将移动数据而不是复制它。)

为了捍卫我刚刚提出的这个相当愚蠢的尝试:我不打算在asm级别上使用我的代码,我只是想要了解R-Value引用所引入的技术差异与已经存在的其余部分相比这些年来。

非常欢迎任何见解和解释!

谢谢!

4 个答案:

答案 0 :(得分:8)

  

创建R值引用时,汇编程序级别会发生什么。

保留高级语义所需的一切。什么编译器完全取决于编译器供应商认为什么是好主意。程序集没有左值,右值或引用的概念,因此请停止查找它们。打开优化,您正在查看的代码可能会更改(或者如果不使用变量,可能会停止存在)。

  

我只是想了解R-Value参考文献所引入的技术差异与这些年来的其他文献差异。

Rvalue引用启用了移动语义,而这些参数又可以实现重要的优化机会。标准没有说“哦,这些是rvalue refs,这就是你应该如何在汇编中实现它们”。实现甚至可能根本不会产生汇编。

答案 1 :(得分:6)

在asm级别上Rvalue引用没有什么不同 - 它可能与常规引用完全相同(取决于编译器如何看待它)。差异仅存在于C ++语言层面。 信息r值引用是指引用的对象是临时的,任何接收它的人都可以自由地修改它。有关对象位置的信息可能与常规引用完全相同(编译器可能会尝试以不同方式对其进行优化,但这是编译器的内部事务)。

r值引用和非const l值引用之间的区别在于每个l值将自动仅转换为l值引用(从而防止意外修改),而r值表达式将转换两者(使用r值ref。优先),如果不支持移动语义,则允许移动语义和常规调用。 std :: move除了允许非自动地将l值转换为r值引用之外别无其他。

答案 2 :(得分:4)

在优化之前,引用存在为包含绑定对象地址的指针。

但编译器非常努力地将其优化掉。内联尤其可能导致在小函数内使用引用参数,直接使用包含绑定对象值的寄存器。

答案 3 :(得分:0)

rvalue引用概念可以在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 ++和Assembly级别上都没有使用这种类型的rvalue引用。所以,如果你没有看到在C ++中使用char&amp;&amp; c的任何优势,那么在Assembly中也没有什么有趣的。