GCC NRVO / RVO предупреждение

Есть ли предупреждение, что позволяет нам знать, NRVO / РВО выполнено или нет, в НКУ?

я нашел это -fno-elide-constructors выключает NRVO / РВО, но NRVO / РВО имеет свои условия для возникновения, а иногда и не происходит. Необходимо знать, NRVO / РВО происходит, чтобы понять, когда происходит дополнительное копирование.

Меня особенно интересуют функции времени компиляции. Было бы неплохо, если бы были какие-то конкретные #pragma GCC... (который активирует диагностику сразу после себя) или что-то, используя механизм статического подтверждения.

18

Решение

Я не знаю ни одного конкретного диагностического сообщения gcc или другого метода, который легко может решить вашу задачу. Как вы узнали, -fno-elide-constructors отключит копирование / перемещение разрешений, так что вы будете точно знать, что (N) RVO не произойдет в этом случае, по крайней мере.

Тем не менее, быстрый взгляд на пункт 31 в разделе 12.8 этот рабочий проект C ++ 11 говорится, что:

При соблюдении определенных критериев реализация может быть опущена
конструкция копирования / перемещения объекта класса, даже если копирование / перемещение
Конструктор и / или деструктор для объекта имеют побочные эффекты. В
такие случаи, реализация рассматривает источник и цель
опущена операция копирования / перемещения просто как два разных способа обращения
к тому же объекту
, и разрушение этого объекта происходит на
позднее, когда два объекта были бы уничтожены
без оптимизации. Это исключение операций копирования / перемещения,
называется копия разрешения, допускается при следующих обстоятельствах
(которые могут быть объединены для устранения нескольких копий):

  • в операторе возврата в функции с типом возврата класса, когда выражение является именем энергонезависимого автоматического объекта (Другой
    чем функция или параметр catch-clause) с тем же cv-unqualified
    введите в качестве типа возврата функции, операция копирования / перемещения может быть
    опускается путем создания автоматического объекта непосредственно в
    возвращаемое значение функции

  • когда временный объект класса, который не был связан со ссылкой (12.2) будет скопирован / перемещен в объект класса с тем же
    cv-unqualified type, операция копирования / перемещения может быть опущена
    строительство временного объекта непосредственно в цель
    опущено копирование / перемещение

Когда происходит копирование / перемещение, локальный автоматический объект совпадает с временным (возвращаемым) объектом, который, в свою очередь, совпадает с объектом «хранения» (где хранится возвращаемое значение). Таким образом, локальный автоматический объект такой же, как и объект хранилища, что означает, что сравнение указателей будет равно true. Простой пример, чтобы продемонстрировать это:

#include <iostream>
#include <vector>

std::vector<int> testNRVO(int value, size_t size, const std::vector<int> **localVec)
{
std::vector<int> vec(size, value);

*localVec = &vec;

/* Do something here.. */

return vec;
}

int main()
{
const std::vector<int> *localVec = nullptr;

std::vector<int> vec = testNRVO(0, 10, &localVec);

if (&vec == localVec)
std::cout << "NRVO was applied" << std::endl;
else
std::cout << "NRVO was not applied" << std::endl;
}

Включение / выключение -fno-elide-constructors изменяет напечатанное сообщение, как и ожидалось. Примечание: в самом строгом смысле сравнение указателей может зависеть от неопределенного поведения, когда (N) RVO не происходит, поскольку локальный автоматический объект не существует.

Выполнение сравнений с указателями добавит бесполезность, но с преимуществом независимости от компилятора.

4

Другие решения

Других решений пока нет …