2010-10-11 13 views
7

Być może zadaję głupie pytanie, ale spojrzałem na stronę wikipedia dla RVO here i nie mogłem przestać się zastanawiać, czy to zachowanie jest złe. Próbowałem go w mojej maszynie, a RVO zostało w pełni wyrzucone pomimo optymalizacji. A co, jeśli rzeczywiście coś się stało w konstruktorze? Wiem, że nie powinno, ale co jeśli? Nie mogę zrozumieć, dlaczego RVO nadal miałoby miejsce, gdyby w konstruktorze wystąpiły efekty uboczne.Czy optymalizacja wartości zwracanej (RVO) nie jest błędem?

EDYCJA: -fno-elide-constructors wydaje się zatrzymać RVO. Ale pozostaje pytanie.

EDIT2: Co ważniejsze, ile osób wie o czymś takim? Być może w standardzie, ale jest to wciąż bardzo brzydka funkcja, jaką widzę. Przynajmniej kompilatory powinny domyślnie go wyłączyć i zapewnić przełącznik dla osób, które o tym wiedzą. :)

EDYCJA 3: Nadal twierdzę, że jest naprawdę źle. :). Nie sądzę, abym znał jakiekolwiek inne ograniczenia językowe, takie jak te, które są sprzeczne ze składnią języka. Wszystko inne powoduje błędy kompilatora lub linkera?

+1

Osobiście uważam, że RVO jest obrzydliwość. –

+10

Czy możesz wymyślić dobry przypadek użycia dla nietrywialnych efektów ubocznych w konstruktorze kopii? Nie mam jednego, bez pomocy. Zwykle są one nazywane za kulisami i naprawdę łatwo popełnić błąd, gdy zastanawiają się, kiedy zostaną wezwani. To dla mnie jest bardzo dobry powód, aby zostawić efekty uboczne. –

+1

Nie mam żadnego powodu, aby umieszczać efekty uboczne wewnątrz konstruktora kopiowania. :) – nakiya

Odpowiedz

20

Standardowe mandaty, że operacje z niepokojem program na stan obserwowalne nie musi być zoptymalizowany daleko, wyjątkiem budowy kopii w pewnych okolicznościach. Nie można polegać na wykonywaniu konstruktorów kopii, nawet jeśli mają efekty uboczne, które spodziewacie się zobaczyć (np. Wyjście konsoli).

+0

Dlatego właśnie przekazywanie wartości jest lepsze? – nakiya

+0

To jeden z powodów, dla których wartość przekazana * może * być lepsza. To też nie jest uniwersalna rada. Czasami wartość przekazywana dopuszcza optymalizacje, które nie byłyby możliwe w przypadku przekazywania przez referencję, ale w niektórych przypadkach może być wolniejsza. :) – jalf

+0

Co więcej, pomyślałem, że boost :: shared_ptr zależy od tych samych dwóch funkcji do liczenia odwołań. Co tu się dzieje? – nakiya

7

Zdefiniuj "źle". Język C++ wyraźnie dopuszcza taką optymalizację, nawet jeśli jest ona obserwowalna. Jeśli zachowanie twojego programu zależy od konkretnej implementacji, to niestety nie używasz ISO C++, ale jakiś dialekt.

13

Jak wspomniano w innych odpowiedziach, kompilator może zoptymalizować nawet niezbyt trywialne konstruktory kopiowania i operatory przypisania.

12.8.15

Kiedy pewne kryteria są spełnione, to implementacja wolno pominąć budowę kopia obiektu klasy, nawet jeśli kopia konstruktor i/lub destruktor dla obiektu mają efekty uboczne. W takich przypadkach implementacja traktuje źródło i cel pominiętej operacji kopiowania jako tylko dwa różne sposoby odwoływania się do tego samego obiektu, a zniszczenie tego obiektu następuje w późniejszym czasie, gdy te dwa obiekty zostałyby usunięte. zniszczona bez optymalizacji . Ta elizacja operacji kopiowania jest dozwolona w następujących okolicznościach (które mogą być połączone w celu wyeliminowania wielu kopii):

- w instrukcji return w funkcji z typem zwracanym przez klasę, gdy wyrażenie jest nazwą -volatile automatycznym obiektu z tego samego CV-niewykwalifikowany typu jak typ zwracany funkcji, operacja kopiowania może zostać pominięty konstruując automatyczną przedmiotu bezpośrednio do wartości zwracanej przez funkcję za

- gdy tymczasowy obiekt klasy, która nie została związany z odniesieniem (12.2) zostaną skopiowane do obiektu klasy z samo cv-niewykwalifikowany typu operacja kopiowania może zostać pominięte poprzez budowę tymczasowego obiektu bezpośrednio do cel zaniechanej kopii

+0

+1 za ofertę, proszę również podać link do kopii standardu do weryfikacji –

+1

@Matt: To sprawi, że będzie to odniesienie do odniesienia. Artykuły naukowe i książki zwykle zawierają tylko BibTex lub nazwę jakiejś książki, nie wspominając o Amazon lub ISO, gdzie można uzyskać te tytuły. W każdym razie, dla Twojej wygody, najnowszy projekt standardu jest dostępny bezpłatnie pod adresem http://open-std.org. –

+0

We współczesnym świecie WWW oczekiwałbym nie mniej niż hiperłącza wskazującego bezpośrednio na ten akapit. W mojej obronie autor tej odpowiedzi nie wskazuje nawet, jaki standard, rok czy wersję, z której ją usunął. –