Ответ 1
Мне неизвестно какое-либо конкретное диагностическое сообщение gcc или другой метод, который легко может решить вашу задачу. Как вы узнали, -fno-elide-constructors
отключит копирование/перемещение элит, так что вы наверняка будете знать, что (N) RVO не произойдет в этом случае по крайней мере.
Тем не менее, быстрый взгляд на пункт 31 раздела 12.8 этот рабочий проект С++ 11 гласит, что:
Когда выполняются определенные критерии, реализация может пропустить копирование/перемещение объекта класса, даже если копирование/перемещение конструктор и/или деструктор объекта имеют побочные эффекты. В в таких случаях реализация рассматривает источник и цель опустить операцию копирования/перемещения как просто два разных способа обращения к тому же объекту, а уничтожение этого объекта происходит на позже того времени, когда два объекта были бы уничтожены без оптимизации. Это исключение операций копирования/перемещения, вызванное копией, разрешено в следующих случаях: (, которые могут быть объединены для устранения нескольких копий):
- в операторе return в функции с типом возвращаемого класса, когда выражение является именем энергонезависимого автоматического объекта (другое чем параметр функции или catch-clause) с тем же cv-unqualified тип как возвращаемый тип функции, операция копирования/перемещения может быть опущено путем создания автоматического объекта непосредственно в функции возвращают значение
...
- , когда объект временного класса, который не был привязан к ссылке (12.2), будет скопирован/перенесен в объект класса с тем же cv-unqualified тип, операция копирования/перемещения может быть опущена построение временного объекта непосредственно в цель omitted copy/move
...
Когда выполняется копирование/перемещение, локальный автоматический объект совпадает с временным (возвращаемым) объектом, который, в свою очередь, совпадает с объектом "хранения" (где хранится возвращаемое значение). Таким образом, локальный автоматический объект совпадает с объектом хранения, что означает, что сравнение указателей будет равно 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
изменяет печатаемое сообщение, как ожидалось. Примечание: в строгом смысле сравнение указателей может зависеть от поведения undefined, когда (N) RVO не происходит, поскольку локальный автоматический объект не существует.
Выполнение сравнения указателей добавит крейт, но с преимуществом независимости от компилятора.