Подтвердить что ты не робот

Почему экземпляр unique_ptr компилируется в более крупный двоичный код, чем исходный указатель?

Мне всегда казалось, что 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()?

4b9b3361

Ответ 1

Поскольку std::make_unique<int[]>(100) выполняет инициализацию значения, а new int[100] выполняет инициализация по умолчанию. В первом случае элементы являются 0-инициализированными (для int), а во втором случае элементы остаются неинициализированными. Попробуйте:

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

И вы получите тот же результат, что и с std::unique_ptr.

См. this, в котором указано, что std::make_unique<int[]>(100) эквивалентно:

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

Если вам нужен неинициализированный массив с std::unique_ptr, вы можете использовать 1:

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

1 Как упоминалось в комментариях @Ruslan, обратите внимание на разницу между std::make_unique() и std::unique_ptr() - См. Различия между std:: make_unique и std:: unique_ptr.