5

我最近一直在玩Compiler Explorer。我加载了一个采用指针参数的示例,并将其更改为采用 unique_ptr 参数。但我注意到在输出程序集中,对 operator delete 的调用明显不存在。我很好奇是否有人知道为什么。

这是一个可以粘贴到资源管理器中的示例。一定要-O3输入编译器选项。

#include <memory>

using std::unique_ptr;

void maxArray(unique_ptr<double[]> x, unique_ptr<double[]> y) {
    for (int i = 0; i < 65536; i++) {
        if (y[i] > x[i]) x[i] = y[i];
    }
}

编辑:同样为了比较,如果我粘贴来自 cppreference 的代码示例之一,那么我在输出中得到 operator delete。

#include <iostream>
#include <memory>

struct Foo
{
    Foo()      { std::cout << "Foo::Foo\n";  }
    ~Foo()     { std::cout << "Foo::~Foo\n"; }
    void bar() { std::cout << "Foo::bar\n";  }
};

void f(const Foo &)
{
    std::cout << "f(const Foo&)\n";
}

int main()
{
    std::unique_ptr<Foo> p1(new Foo);  // p1 owns Foo
    if (p1) p1->bar();

    {
        std::unique_ptr<Foo> p2(std::move(p1));  // now p2 owns Foo
        f(*p2);

        p1 = std::move(p2);  // ownership returns to p1
        std::cout << "destroying p2...\n";
    }

    if (p1) p1->bar();

    // Foo instance is destroyed when p1 goes out of scope
}

编辑:+1 给 krzaq。构造和销毁参数的是调用者,而不是被调用者。

4

1 回答 1

6

这个问题归结为:

void foo(unique_ptr<int>)
{
}

foo(make_unique<int>());

的参数在哪里foo

以下标准语与此问题有关:

N4140 §5.2.2 [expr.call]/4

参数的生命周期在定义它的函数返回时结束。每个参数的初始化和销毁​​发生在调用函数的上下文中。

换句话说:你maxArray不需要负责调用xandy的析构函数;gcc 以这种方式实现它,这就是为什么在 codegen 中没有delete调用。

于 2016-10-16T03:13:16.717 回答