2012-04-06 17 views
10

W wywiadzie programowania miałem wczoraj jeden z programów miałem napisać skończyło się coś takiego:RVO dla złożonych typów zdefiniowanych przez użytkownika w języku C++

struct Blob 
{ 
    // basic field containing image blob statistics. 
}; 

std::vector<Blob> find_blobs (const Image& ...) 
{ 
    std::vector<Blob> blobs; 
    // ... 
    return blobs; 
} 

Znam return value optimization (RVO), więc właśnie wspomniałem, że zwrócenie wektora nie spowoduje kopii na popularnych kompilatorach (istnieje jedna instrukcja return jako ostatnia linia, a żadne ścieżki kontrolne nie mogą zwrócić innego obiektu w kodzie, który napisałem).

Jednak ankieter powiedział mi, że ponieważ Blob może być złożonym typem zdefiniowanym przez użytkownika (UDT), kompilator może nie być w stanie wykonać RVO. Dodał, że zwrócenie wartości std::vector<Blob*> zwiększy szanse, że kompilator wykona kopiowanie. Zgodnie z moją wiedzą, wydajność kompilatora w wykonywaniu RVO jest całkowicie nieistotna dla zwracanego obiektu, z wyjątkiem obiektów niekopiowalnych, dla których kompilator (powinien?) Odrzucić kod nawet jeśli wynikowy kod mógłby się skompilować bez wywoływania konstruktora kopiowania.

Czy wywiad był właściwy? Czy złożony typ zwracany może uniemożliwić kompilatorowi zastosowanie RVO?

+4

Ktokolwiek przeprowadzał z tobą wywiad, nie zatrudniłbym. :) –

+0

@ Robᵩ: Nie mówię, kto to był, ani dla kogo pracują (lub na to pytanie dotyczące wywiadu) :-) –

Odpowiedz

7

Nie, użyte typy nie powinny wpływać na optymalizację.

Jedynym powodem, dla którego używam wskaźników, jest to, że są one tańsze w kopiowaniu , jeśli kompilator nie powiedzie się z RVO. Nie jest prawdopodobne w przypadku najpopularniejszych kompilatorów.

+0

Rzeczywiście, gdyby kompilator wykonał kopię, skopiowanie wektora wskaźników byłoby tańsze (choć w tym przypadku 'BLOB' był POD z 2-3 polami typów pierwotnych, co skutkowało nieco większym' memcpy() '). Jednak wymagałoby to jawnego zarządzania pamięcią ze strony osoby dzwoniącej i staram się tego unikać tak bardzo, jak to tylko możliwe. –

+0

Tak, używanie wskaźnika nie jest zalecane, chyba że użytkownik jest do tego zmuszony. Kompilatory takie jak g ++ wykonują tę optymalizację nawet na najniższym poziomie optymalizacji, '-O0'. Ale nie wiem, czego używa twój potencjalny pracodawca (?). ;-) –

+0

Tak, myślę, że g ++ zawsze stosuje RVO, chyba że jawnie wyłączysz go za pomocą '-fno-elide-constructors'. MSVC 2008 wykonuje go nawet w trybie debugowania (właśnie zweryfikowaliśmy na przykładzie). AFAIK, ten potencjalny pracodawca używa wszystkich popularnych kompilatorów (dobrze, przynajmniej g ++ i MSVC). –