Есть ли предупреждение, что позволяет нам знать, NRVO / РВО выполнено или нет, в НКУ?
я нашел это -fno-elide-constructors
выключает NRVO / РВО, но NRVO / РВО имеет свои условия для возникновения, а иногда и не происходит. Необходимо знать, NRVO / РВО происходит, чтобы понять, когда происходит дополнительное копирование.
Меня особенно интересуют функции времени компиляции. Было бы неплохо, если бы были какие-то конкретные #pragma GCC...
(который активирует диагностику сразу после себя) или что-то, используя механизм статического подтверждения.
Я не знаю ни одного конкретного диагностического сообщения 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 не происходит, поскольку локальный автоматический объект не существует.
Выполнение сравнений с указателями добавит бесполезность, но с преимуществом независимости от компилятора.
Других решений пока нет …