【问题标题】:Why does unique_ptr instantiation compile to larger binary than raw pointer?为什么 unique_ptr 实例化编译为比原始指针更大的二进制文件?
【发布时间】:2017-03-30 19:50:54
【问题描述】:

我一直认为std::unique_ptr 与使用原始指针相比没有开销。但是,编译如下代码

#include <memory>

void raw_pointer() {
  int* p = new int[100];
  delete[] p;
}

void smart_pointer() {
  auto p = std::make_unique<int[]>(100);
}

使用g++ -std=c++14 -O3 生成以下程序集:

raw_pointer():
        sub     rsp, 8
        mov     edi, 400
        call    operator new[](unsigned long)
        add     rsp, 8
        mov     rdi, rax
        jmp     operator delete[](void*)
smart_pointer():
        sub     rsp, 8
        mov     edi, 400
        call    operator new[](unsigned long)
        lea     rdi, [rax+8]
        mov     rcx, rax
        mov     QWORD PTR [rax], 0
        mov     QWORD PTR [rax+392], 0
        mov     rdx, rax
        xor     eax, eax
        and     rdi, -8
        sub     rcx, rdi
        add     ecx, 400
        shr     ecx, 3
        rep stosq
        mov     rdi, rdx
        add     rsp, 8
        jmp     operator delete[](void*)

为什么smart_pointer() 的输出几乎是raw_pointer() 的三倍?

【问题讨论】:

  • 我真的很惊讶整个事情没有完全优化。
  • @SergeyA 叮当响。
  • 是的,我正在同时检查它。看起来 CLang 开始使用 gcc 进行优化。
  • @SergeyA 如果它是单独编译的,我猜编译器必须允许您重载 newdelete 以产生其他副作用?
  • @EdHeal 计数器?虚拟表?这并不真正适用于std::unique_ptr,是吗?

标签: c++ assembly smart-pointers


【解决方案1】:

因为std::make_unique&lt;int[]&gt;(100) 执行value initializationnew int[100] 执行default initialization - 在第一种情况下,元素初始化为0(对于int),而在第二种情况下,元素未初始化。试试:

int *p = new int[100]();

您将获得与 std::unique_ptr 相同的输出。

例如,参见this,它指出std::make_unique&lt;int[]&gt;(100) 等同于:

std::unique_ptr<T>(new int[100]())

如果你想要一个带有std::unique_ptr 的未初始化数组,你可以使用1:

std::unique_ptr<int[]>(new int[100]);

1 正如 @Ruslan 在 cmets 中所提到的,请注意 std::make_unique()std::unique_ptr() 之间的区别 - 请参阅 Differences between std::make_unique and std::unique_ptr

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-09-25
  • 1970-01-01
  • 2018-09-25
  • 1970-01-01
  • 2013-05-19
  • 2021-07-15
  • 1970-01-01
  • 2019-11-07
相关资源
最近更新 更多