Try   HackMD

01 Лекция, передача параметров по значению, RVO, NRVO

(03.09.2022)

Онлайн компилятор (показывает ассемблер)

Зачем?

#include <string>
#include <vector>

int main()
{
    std::string hello = "Hello";
    std::vector<std::string> v;
    v.push_back(hello); //тут есть копирование
}

#include <vector>

int main()
{
    std::vector<std::fstream*> v;
    
    v.push_back(new std::fstream("1.txt"));//небезопасная строчка, вызывается исключение
}

#include <vector>

int main()
{
    std::vector<std::shared_ptr<std::fstream>> v;
    
    v.push_back(std::make_shared<<std::fstream>()); //будет работать
}

Где НЕ возникает копирование

#include <string>

std::string g();

void f(std::string);

int main()
{
    f(g()); //здесь НЕТ копирования
}

Общее

Функции неявно передается указатель куда должен записаться результат выполнения функции, хранится до тех пор, пока не пригодится.

RVO

Return value optimization - при передачи r-value выражений копий не делается (обязательна с C++17)

struct mytype{};

int main()
{
    mytype y;
    f(y);         //y - lvalue, copy
    f(mytype());  // mytype() - r-value, no copy
    f(g());       // g() - r-value, no copy
}

NRVO

Named return value optimization - будет оптимизированна переменная которая возвращается (не обязательная) (В return можно не делать копию)

Подробнее

Нельзя сделать NRVO когда есть выборность обьектов для return:

int a()
{
    int a, b;
    if(rand())
    {
        return a; //Здесь нет NRVO
    }
    else
    {
        return b; //Здесь нет NRVO
    }
}

GCC не всегда справляеться с NRVO (если убрать все в ещё одни {} то NRVO не будет)

Оглавление