origin

今天(2019-6-10)看书的时候, 提到了thred传引用, 需要使用 std::ref()

很好奇他做了什么, 所以有了这篇笔记

 

首先, 是简单的代码

func分为了两种传参, 一种是值, 一种是引用, 关键代码汇编如下:

其中的关键就在于, leaq是取地址, 而movl是值

然后来看一下, std::ref()做了什么

为了完整看到过程, 所以使用的是objdump

可以看到, 在第一次的call中, 对-0x10(%rbp) 和 -0x14(%rbp)做了什么

以致于后面直接使用 -0x10(%rbp) 调用第二个函数, 其返回值直接用于了参数传递

首先看 callq 4008e8 <ZSt3refIiESt17reference_wrapperIT_ERS1>

我隐藏了其中无用的委托调用, 这是经过委托后调用的代码

这几行汇编应该是做一些初始化工作

其中关键在这里的

其中 rax 存储的是 rsi 也就是原来的 -0x14(%rbp) 也就是 i 的地址

而 rdx 则是 -0x10(%rbp) 一个额外申请的空间, 其中这块空间的值是 i 的地址 !

那么就很容易联想到, 这个就是指针, std::ref() 就相当于创建了一个指针指向对象, 然后将指针传递

那么第二次调用大概率也能猜到做了什么: 将这个指针解引用, 获得原变量的地址, 传参

而事实也的确如此(当然, 这也经过了委托, 我删减了一部分 = = ... )

拿到参数, 解引用, 返回, 就相当于一个 *p

 

summary

std::ref()就相当于创建了一个二级指针, 指向对象的地址

而使用时, 会将其解引用(这会获得原对象的地址), 然后传参

那为什么不单纯的一级指针, 获取其地址, 直接传参呢?

emmm... 我也不清楚...