首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么这个死掉的unique_ptr商店不能被消除?

为什么这个死掉的unique_ptr商店不能被消除?
EN

Stack Overflow用户
提问于 2018-11-16 02:02:09
回答 1查看 149关注 0票数 3
代码语言:javascript
复制
#include <memory>
#include <vector>
using namespace std;

vector<unique_ptr<int>> e;

void f(unique_ptr<int> u) {
    e.emplace_back(move(u));
}

对于嘎吱声GCC,上面的代码段生成如下内容:

代码语言:javascript
复制
f(std::unique_ptr<int, std::default_delete<int> >):
        mov     rsi, QWORD PTR e[rip+8] # rsi: vector.end_ptr
        cmp     rsi, QWORD PTR e[rip+16] # [e + rip + 16]: vector.storage_end_ptr
        je      .L52 # Slow path, need to reallocate
        mov     rax, QWORD PTR [rdi] # rax: unique_ptr<int> u
        add     rsi, 8               # end_ptr += 8
        mov     QWORD PTR [rdi], 0   # <==== Do we need to set the argument u to null here? 
        mov     QWORD PTR [rsi-8], rax # *(end_ptr - 8) = u 
        mov     QWORD PTR e[rip+8], rsi # update end_ptr
        ret
.L52:   # omitted

我想知道为什么编译器会在这个函数中生成mov QWORD PTR[rdi], 0?是否有任何要求编译器这样做的约定?

此外,对于更简单的情况,如

代码语言:javascript
复制
void f(unique_ptr<int> u);

void h(int x) {
    auto p = make_unique<int>(x);
    f(move(p));
}

为什么编译器会生成:

代码语言:javascript
复制
call    operator delete(void*, unsigned long)

h()的末尾,假设在调用f之后p总是nullptr

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-16 02:41:45

在这两种情况下,答案都是:因为您移动的对象仍将被销毁。

如果您查看为调用

代码语言:javascript
复制
void f(unique_ptr<int> u);

您将注意到,调用方为参数u创建对象,然后按照调用约定的要求调用其析构函数。如果对f()的调用是内联的,编译器很可能会优化它。但是为f()生成的代码无法控制u的析构函数,因此必须将u的内部指针设置为零,前提是u的析构函数将在函数返回后运行。

在第二个例子中,我们有一些相反的情况:

代码语言:javascript
复制
void h(int x) {
    auto p = make_unique<int>(x);
    f(move(p));
}

与名称可能相反的是,std::move()实际上并不移动对象。它所做的就是转换为一个rvalue引用,它允许引用的接收方从所引用的对象中移动--如果他这样选择的话。实际的移动只会发生,例如,当另一个对象通过移动构造函数从给定的参数构造时。由于编译器在定义f()时不知道h()内部发生了什么,所以不能假设f()总是从给定的对象移动。例如,f()只能在某些情况下返回或移动,而在其他情况下则不能。因此,编译器必须假设函数可能返回而不移动对象,并且必须为析构函数发出delete。该函数还可以执行移动分配,而不是移动构造,在这种情况下,仍然需要外部析构函数来释放以前由新对象…的指定所有权所持有的对象的所有权。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53330428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档