Co to jest kopia prawna? Czym jest (nazwana) optymalizacja wartości zwracanej? Co oni implikują?
W jakich sytuacjach mogą wystąpić? Jakie są ograniczenia?
- Jeśli odniesiono Cię do tego pytania, prawdopodobnie szukasz wprowadzenia .
- Przegląd techniczny znajduje się w standardowej dokumentacji .
- Zobacz typowe przypadki tutaj .
c++
optimization
c++-faq
return-value-optimization
copy-elision
Luchian Grigore
źródło
źródło
Odpowiedzi:
Wprowadzenie
Przegląd techniczny - przejdź do tej odpowiedzi .
W typowych przypadkach, w których występuje usuwanie kopii, przejdź do tej odpowiedzi .
Eliminacja kopiowania to optymalizacja realizowana przez większość kompilatorów w celu zapobiegania dodatkowym (potencjalnie drogim) kopiom w niektórych sytuacjach. W praktyce umożliwia to zwrot według wartości lub według wartości (obowiązują ograniczenia).
Jest to jedyna forma optymalizacji, która wymusza (ha!) Zasadę „jak gdyby” - można zastosować eliminację kopiowania, nawet jeśli kopiowanie / przenoszenie obiektu ma skutki uboczne .
Poniższy przykład pochodzi z Wikipedii :
W zależności od kompilatora i ustawień wszystkie poniższe dane wyjściowe są prawidłowe :
Oznacza to również, że można utworzyć mniej obiektów, więc nie można również polegać na wywołaniu określonej liczby niszczycieli. Nie powinieneś mieć krytycznej logiki wewnątrz konstruktorów kopiowania / przenoszenia lub destruktorów, ponieważ nie możesz polegać na ich wywoływaniu.
Jeśli zostanie wywołane wywołanie konstruktora kopiowania lub przenoszenia, konstruktor ten musi nadal istnieć i musi być dostępny. Zapewnia to, że usuwanie kopii nie pozwala na kopiowanie obiektów, których normalnie nie można skopiować, np. Ponieważ mają one prywatny lub usunięty konstruktor kopiowania / przenoszenia.
C ++ 17 : Począwszy od C ++ 17, Copy Elision jest gwarantowane, gdy obiekt jest zwracany bezpośrednio:
źródło
Standardowe odniesienie
Aby uzyskać mniej techniczny widok i wprowadzenie - przejdź do tej odpowiedzi .
W typowych przypadkach, w których występuje usuwanie kopii, przejdź do tej odpowiedzi .
Skasowanie kopii jest zdefiniowane w standardzie w:
12.8 Kopiowanie i przenoszenie obiektów klasy [class.copy]
tak jak
Podany przykład to:
i wyjaśnił:
źródło
Typowe formy wyboru kopii
Przegląd techniczny - przejdź do tej odpowiedzi .
Aby uzyskać mniej techniczny widok i wprowadzenie - przejdź do tej odpowiedzi .
(Nazwany) Optymalizacja wartości zwracanej jest powszechną formą usuwania kopii. Odnosi się do sytuacji, w której obiekt zwrócony przez wartość z metody ma swoją kopię. Przykład podany w standardzie ilustruje optymalizację nazwanych wartości zwrotnych , ponieważ obiekt jest nazwany.
Regularna optymalizacja wartości zwracanej następuje po zwróceniu wartości tymczasowej:
Inne typowe miejsca, w których odbywa się usuwanie kopii, to moment, w którym wartość tymczasowa jest przekazywana :
lub gdy wyjątek jest zgłaszany i wychwytywany według wartości :
Typowe ograniczenia wyboru kopii to:
Większość komercyjnych kompilatorów obsługuje usuwanie kopii i (N) RVO (w zależności od ustawień optymalizacji).
źródło
Copy elision to technika optymalizacji kompilatora, która eliminuje niepotrzebne kopiowanie / przenoszenie obiektów.
W następujących okolicznościach kompilator może pominąć operacje kopiowania / przenoszenia, a tym samym nie wywoływać powiązanego konstruktora:
Nawet jeśli ma miejsce usuwanie kopii i nie wywoływany jest konstruktor kopiowania / przenoszenia, musi on być obecny i dostępny (tak jakby w ogóle nie nastąpiła optymalizacja), w przeciwnym razie program będzie źle sformułowany.
Powinieneś zezwolić na taką kopię kopii tylko w miejscach, w których nie wpłynie to na obserwowalne zachowanie twojego oprogramowania. Kopiowanie danych jest jedyną formą optymalizacji, która może mieć (tzn. Uniknąć) obserwowalne skutki uboczne. Przykład:
GCC zapewnia
-fno-elide-constructors
opcję wyłączenia kopiowania. Jeśli chcesz uniknąć możliwego usunięcia kopii, użyj-fno-elide-constructors
.Teraz prawie wszystkie kompilatory zapewniają usuwanie kopii, gdy optymalizacja jest włączona (i jeśli nie ustawiono żadnej innej opcji, aby ją wyłączyć).
Wniosek
Przy każdym usuwaniu kopii pomijana jest jedna konstrukcja i jedno pasujące zniszczenie kopii, co oszczędza czas procesora, a jeden obiekt nie jest tworzony, co oszczędza miejsce na ramce stosu.
źródło
ABC obj2(xyz123());
to NRVO czy RVO? czy nie otrzymuje tymczasowej zmiennej / obiektu tak jakABC xyz = "Stack Overflow";//RVO