Ich habe festgestellt, dass der Intel-Compiler keine Rückgabewertoptimierung für std :: array-Objekte generiert. Der folgende Code, der sich zufällig in der inneren Schleife meines Programms befindet, ist nicht so optimiert, wie er könnte.Muss die Rückgabewertoptimierung einen Kopierkonstruktor deklarieren
std::array<double, 45> f(const std::array<double, 45>& y) {
auto dy_dt = std::array<double, 45>();
...
return dy_dt;
}
Ich habe herausgefunden, dass dieses Verhalten kommt von der Tatsache, dass meine Standard-Bibliothek Implementierung eine Kopie Konstruktor für nicht explizit std :: Array definieren. Der folgende Code zeigt, dass:
class Test {
public:
Test() = default;
Test(const Test& x);
};
Test f() {
auto x = Test();
return x;
}
Wenn Sie es kompilieren mit
icpc -c -std=c++11 -qopt-report=2 test.cpp -o test.o
der Report-Datei zeigt
INLINE REPORT: (f(Test *)) [1] main.cpp(7,10)
was beweist, dass der Compiler RVO erzeugt (die Signatur von f geändert wird Damit kann das neu erstellte Objekt auf dem Stapel der aufrufenden Site abgelegt werden. Aber wenn Sie die Zeile aus kommentieren, die Test(const Test& x);
erklärt, die Report-Datei zeigt
INLINE REPORT: (f()) [1] main.cpp(7,10)
was beweist, dass RVO nicht erzeugt wird.
In 12.8.31 des C++ 11-Standards, der RVO definiert, hat das Beispiel, das sie geben, einen Kopierkonstruktor. Also, ist das ein "Bug" des Intel-Compilers oder eine konforme Implementierung des Standards?
@ Cyber Nein, wenn RVO möglich wäre, würde es die Kopie elide. – juanchopanza
Cyber: Nein, das ist die Rückgabewert-Optimierung, die hier involviert ist. Es hat nichts mit der Bewegungssemantik zu tun. – InsideLoop
RVO benötigt keinen Kopierkonstruktor, aber Code, für den RVO gelten würde, benötigt einen gültigen Kopier- oder Verschiebekonstruktor, um verfügbar zu sein. – juanchopanza