Как избежать «пессимизирующего» предупреждения NRVO? - PullRequest
2 голосов
/ 28 мая 2020
#include <string>

std::string f()
{
    std::string s;
    return std::move(s);
}

int main()
{
    f();
}

g++ -Wall z.cpp выдает следующее предупреждение:

z.cpp: In function ‘std::string f()’:
z.cpp:6:21: warning: moving a local object in a return statement prevents copy elision [-Wpessimizing-move]
    6 |     return std::move(s);
      |            ~~~~~~~~~^~~
z.cpp:6:21: note: remove ‘std::move’ call

Я знаю, что если я изменю return std::move(s); на return s;, предупреждения не будет. Однако, согласно стандарту C ++, , NRVO, скажем, в этом случае, не гарантируется. Если я напишу return s;, я не уверен, будет ли выполнено NRVO.

Как облегчить чувство неуверенности?

Ответы [ 2 ]

4 голосов
/ 28 мая 2020

Вы должны сделать

std::string f()
{
    std::string s;
    return s;
}

, если NRVO не применяется, перемещение выполняется автоматически.

См. return # Automatic_move_from_local_variables_and_parameters .

0 голосов
/ 28 мая 2020

Как избежать предупреждения о "пессимизирующем движении" NRVO?

Просто удалите std::move. Здесь он не делает ничего полезного, но предотвращает исключение хода.

Если я напишу return s;, я не уверен, будет ли выполнено NRVO.

Как сделать облегчить чувство неопределенности?

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

Если вы действительно хотите избежать любого перемещения, то возвращайте prvalue, а не lvalue. Это гарантированно будет исключено, поскольку C ++ 17:

std::string f()
{
    return {};
}
...