TGViewer
Грокаем C++ Грокаем C++ @grokaemcpp · 9.36K subscribers
Post #842 4.89K
Zero-Cost Abstraction. Или нет?
#опытным

Концепция бесплатных абстракций-то есть. Но концепции они обычно в банках-консервах хранятся. В реальности все немного сложнее и бесплатный только труд стажеров в современном IT.

Вот как много из вас думает, что уникальный указатель - это бесплатная абстракция? Думаю, что очень многие. Но давайте посмотрим на реальность.

Для чего используется уникальный указатель? Чтобы избавиться от сырых указателей, снять головную боль по освобождению памяти и четко показать в коде передачу владения. То есть такой код:

void bar(int *ptr);

// Takes ownership
void baz(int *ptr);

void foo(int *ptr) {
if (*ptr > 42) {
bar(ptr);
*ptr = 42;
}
baz(ptr);
}


хорошо бы переписать с использованием std::unique_ptr:

void bar(int *ptr);

// Takes ownership.
void baz(std::unique_ptr<int> ptr);

void foo(std::unique_ptr<int> ptr) {
if (*ptr > 42) {
bar(ptr.get());
*ptr = 42;
}
baz(std::move(ptr));
}


Будет ли здесь оверхэд рантайма? Ох-ох-ох, еще как!

Вот асм для первого сниппета:

foo(int):
cmpl $43, (%rdi)
jl baz(int)@PLT
pushq %rbx
movq %rdi, %rbx
callq bar(int)@PLT
movq %rbx, %rdi
movl $42, (%rbx)
popq %rbx
jmp baz(int)@PLT


А вот для второго:

foo(std::unique_ptr<int, std::default_delete<int>>):
pushq %rbx
subq $16, %rsp
movq %rdi, %rbx
movq (%rdi), %rdi
cmpl $43, (%rdi)
jl .LBB0_2
callq bar(int)@PLT
movq (%rbx), %rdi
movl $42, (%rdi)
.LBB0_2:
movq %rdi, 8(%rsp)
movq $0, (%rbx)
leaq 8(%rsp), %rdi
callq baz(std::unique_ptr<int, std::default_delete<int>>)@PLT
movq 8(%rsp), %rdi
testq %rdi, %rdi
je .LBB0_5
movl $4, %esi
callq operator delete(void, unsigned long)@PLT
.LBB0_5:
addq $16, %rsp
popq %rbx
retq
movq %rax, %rbx
movq 8(%rsp), %rdi
testq %rdi, %rdi
je .LBB0_8
movl $4, %esi
callq operator delete(void, unsigned long)@PLT
.LBB0_8:
movq %rbx, %rdi
callq _Unwind_Resume@PLT


Он в 4 раза больше! Если внимательно присмотреться, то можно увидеть, что значительная часть кода здесь тратится на подчищение памяти и обработку исключений. Да, исключения - это вещь, где RAII очень сильно помогает. Вот вам ссылочки на годболт: тык и тык


Но предположим, что изначальный код был корректным и там не вылетало никаких исключений. Пометим функции как noexcept:

void bar(int *ptr) noexcept;

void baz(std::unique_ptr<int> ptr) noexcept;

void foo(std::unique_ptr<int> ptr) {
if (*ptr > 42) {
bar(ptr.get());
*ptr = 42;
}
baz(std::move(ptr));
}


Вот асм:

foo(std::unique_ptr<int, std::default_delete<int>>):
pushq %rbx
subq $16, %rsp
movq %rdi, %rbx
movq (%rdi), %rdi
cmpl $43, (%rdi)
jl .LBB0_2
callq bar(int)@PLT
movq (%rbx), %rdi
movl $42, (%rdi)
.LBB0_2:
movq %rdi, 8(%rsp)
movq $0, (%rbx)
leaq 8(%rsp), %rdi
callq baz(std::unique_ptr<int, std::default_delete<int>>)@PLT
movq 8(%rsp), %rdi
testq %rdi, %rdi
je .LBB0_4
movl $4, %esi
callq operator delete(void, unsigned long)@PLT
.LBB0_4:
addq $16, %rsp
popq %rbx
retq


Стало чуть меньше, но это явно не zero-cost.

Любую проблему можно решить с помощью введения дополнительного уровня индирекции, но эти индирекции накладывают свои косты.

Этот пост не для того, чтобы не пользоваться абстракциями. Просто у всего есть цена и надо это осознавать и в жизни, и при написании программ.

Be aware about costs. Stay cool.
  • 👍 23
  • ❤ 11
  • 🔥 9
  • 🤯 3
  • 😁 2
More from @grokaemcpp
  1. Oct 12, 2026​​WAT #новичкам Как вы думаете, результат выражения: bool math = -1 < 1U; будет правдой ил…
  2. Oct 8, 2026​​Strict weak ordering #опытным На первый взгляд, всё выглядит рабочим: мы создаём 40 зака…
  3. Oct 7, 2026​​Где-то баг... #опытным Вот вам код: struct Order { int price; int id; }; int main() { st…
  4. Oct 5, 2026Откуда spurious wakeup на кондваре? #опытным У кондваров есть метод std::condition_variabl…
  5. Oct 1, 2026​​Stacktrace. Tips #опытным Чтобы полноценно работать со стандартными трейсами, нужно знат…
  6. Sep 28, 2026​​Stacktrace #опытным Одна из проблема исключений - непонятно, откуда оно прилетело. Ну да…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →