tgoop.com/cxx95/11
Create:
Last Update:
Last Update:
#compiler
Как в компиляторе реализуют NRVO?
(и почему он не всегда работает)
Для подробной информации о явлении можно прочитать на cppreference.NRVO (Named Return Value Optimization) - это оптимизация из класса copy elision. Copy elision это отсутствие вызова конструкторов копирования/мува за счёт того, что объект изначально создается в целевом месте.
Оптимизация RVO (Return Value Optimization) выглядит чуть проще:
std::string foo1() {
return std::string("bar");
}
std::string f = foo1();
Компилятор может понять, что никакой нужды в вызове copy/move нет - надо заранее выделить место на стеке под std::string f и создать строку туда.Даже если copy/move ctors имеют побочные эффекты, их все равно не вызовут. Эти конструкторы можно объявить
= delete, или объявить без определения, или сделать private - это ни на что не повлияет.Эта оптимизация старая, все компиляторы ее делают, а с C++17 она стала обязательной при определенных условиях.
Оптимизация
NRVO сложнее, но она не обязательная (в отличие от RVO) - компилятор может сгенерировать суб-оптимальный код.Условие здесь похожее - если у нас все
return xxx; внутри метода возвращают один и тот же xxx;, то в таком случае тоже не происходит copy/move:std::string foo2() {
std::string y = "I'm a redundant string";
std::string x = "sample text";
if (x.size() % 2 == 0) {
return x;
}
x += "xxx";
return x;
}
std::string f = foo2(); // без копирования
Как мы видим, все return возвращают одно и то же, поэтому NRVO сработает. Если бы у нас где-нибудь был return y; или return std::move(x);, то NRVO бы не сработал.Как вычисление NRVO происходит в компиляторе Clang?
Во время парсинга файла Clang держит стек scope (думаю +- понятно для чего нужны скоупы). Одни scope вложены в другие scope, и образуют дерево из scope.
Свой scope создается для каждого метода, каждого класса, каждого if-выражения, каждого for-loop, и так далее. Самый "высокоуровневый" scope это scope Translation Unit-а.
BY C++95
Share with your friend now:
tgoop.com/cxx95/11
