7

可能重复:
右值引用和左值引用有什么区别?(代码生成)

我想知道,谁能在技术层面上解释一下 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

到目前为止,我还不是 asm 专家,但在我看来,在这种情况下,“c3”最终是对“c”的常规引用。

如果我将 R-Value 引用直接绑定到一个临时值(char &&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),以便编码人员知道如何处理提供的数据(对于 move-ctor那将是移动数据而不是复制它)。

为了捍卫我刚刚提出的这个相当愚蠢的尝试:我不打算在 asm 级别上搞砸我的代码,我只是想了解这些年来 R-Value 引用与其他引用相比引入了哪些技术差异。

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

谢谢!

4

4 回答 4

8

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

保留高级语义所需的一切。什么编译器完全取决于编译器供应商认为什么是一个好主意。汇编没有左值、右值或引用的概念,所以不要再寻找它们了。打开优化,您正在查看的代码可能会更改(或者可能根本不存在,如果不使用变量)。

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

右值引用启用了移动语义,而这些又启用了重要的优化机会。标准并没有说“哦,这些是右值引用,这就是你应该在汇编中实现它们的方式”。实现甚至可能根本不会产生汇编。

于 2011-09-29T16:09:14.130 回答
6

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

右值引用和非 const 左值引用之间的区别在于,每个左值都将自动转换为左值引用(从而防止意外修改),而右值表达式将转换为两者 (使用 r-value ref.preffered),如果不支持移动语义,则允许移动语义和常规调用。std::move 除了允许将左值非自动转换为右值引用之外,什么也没做。

于 2011-09-29T16:21:27.330 回答
4

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

但是编译器非常努力地优化它。尤其是内联可能会导致小函数内所有引用参数的使用都被直接使用包含绑定对象值的寄存器所取代。

于 2011-09-29T16:09:29.587 回答
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 这样的简单类型——它们可以用来演示一些右值引用语法特性,但是在这种类型上使用右值引用是没有意义的——无论是在 C++ 还是在汇编级别。因此,如果您没有看到在 C++ 中使用 char &&c 的任何优势,那么在汇编中也没有什么有趣的。

于 2011-09-29T16:27:23.503 回答