Я смотрю выступление Чендлера Каррута в CppCon 2019:
Нет абстракций с нулевой стоимостью
в нем он приводит пример того, как он был удивлен тем, сколько накладных расходов вы понесли, используя std::unique_ptr<int>
над int*
; этот сегмент начинается примерно в момент времени 17:25.
Вы можете взглянуть на результаты компиляции его примера пары фрагментов (godbolt.org) - чтобы убедиться, что, действительно, кажется, что компилятор не хочет передавать значение unique_ptr - которое в Дело в том, что в нижней строке просто адрес - внутри регистра, только в прямой памяти.
Около 27:00 г-н Каррут отмечает, что ABI C++ требует, чтобы параметры по значению (некоторые, но не все; возможно, непримитивные типы? Нетривиально-конструируемые типы?) Передавались в -память, а не в реестре.
Мои вопросы:
- Это требование ABI на некоторых платформах? (что?) Или, может быть, это просто пессимизация в определенных сценариях?
- Почему ABI такой? То есть, если поля структуры/класса вписываются в регистры или даже в один регистр - почему мы не можем передать его в этот регистр?
- Обсуждает ли этот комитет по стандартам C++ этот вопрос в последние годы или когда-либо?
PS - чтобы не оставить этот вопрос без кода:
Обычный указатель:
void bar(int* ptr) noexcept;
void baz(int* ptr) noexcept;
void foo(int* ptr) noexcept {
if (*ptr > 42) {
bar(ptr);
*ptr = 42;
}
baz(ptr);
}
Уникальный указатель:
using std::unique_ptr;
void bar(int* ptr) noexcept;
void baz(unique_ptr<int> ptr) noexcept;
void foo(unique_ptr<int> ptr) noexcept {
if (*ptr > 42) {
bar(ptr.get());
*ptr = 42;
}
baz(std::move(ptr));
}