2012-04-06 13 views
10

In un'intervista di programmazione che ho avuto ieri, uno dei programmi che ho dovuto scrivere finito per avere qualcosa di simile:RVO per complessi tipi definiti dall'utente in C++

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

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

ho familiarità con return value optimization (RVO), quindi ho appena detto che restituire il vettore non causerebbe una copia su compilatori popolari (c'è una singola dichiarazione di ritorno come ultima riga, e nessun percorso di controllo può restituire un altro oggetto nel codice che ho scritto).

Tuttavia, l'intervistatore mi ha detto che dal Blob potrebbe essere un tipo definito dall'utente complesso (UDT), il compilatore potrebbe non essere in grado di eseguire RVO. Ha inoltre aggiunto che restituire un std::vector<Blob*> aumenterebbe le possibilità che il compilatore esegua la copia elision.

Per quanto mi risulta, la capacità del compilatore di eseguire RVO è completamente irrilevante rispetto al tipo di oggetto restituito, salvo per oggetti non copiabili, per i quali il compilatore (dovrebbe?) Rifiuta il codice anche se il codice risultante potrebbe compilare senza mai richiamare il costruttore di copie.

Quindi, l'intervistatore era giusto? Un tipo di ritorno complesso può impedire al compilatore di applicare RVO?

+4

Chiunque ti stia intervistando, non lo assumerebbe. :) –

+0

@ Robᵩ: Non sto affermando chi è stato, o per chi lavorano (o la vera domanda dell'intervista) :-) –

risposta

7

No, i tipi utilizzati non dovrebbero influire sull'ottimizzazione.

L'unico motivo per cui vedo utilizzare i puntatori sarebbe che sono meno costosi da copiare se il compilatore non riesce il RVO. Non probabile con i compilatori più popolari.

+0

Infatti, se il compilatore eseguisse una copia, la copia di un vettore di puntatori sarebbe più economico (anche se in questo caso, 'BLOB' era un POD con 2-3 campi di tipi primitivi che risulta in un' memcpy() ') leggermente più grande. Tuttavia, ciò richiederebbe una gestione esplicita della memoria da parte del chiamante e cerco di evitarlo il più possibile. –

+0

Sì, l'uso del puntatore non è raccomandato, a meno che non sia forzato. I compilatori come g ++ eseguono questa ottimizzazione anche con il livello di ottimizzazione più basso, '-O0'. Ma non so quale sia il tuo potenziale datore di lavoro (?). ;-) –

+0

Sì, penso che g ++ applica sempre RVO a meno che non lo disabiliti esplicitamente usando '-fno-elide-constructors'. MSVC 2008 esegue anche in modalità di debug (ho appena verificato con un esempio). AFAIK, questo potenziale datore di lavoro utilizza tutti i compilatori popolari (beh, almeno g ++ e MSVC). –

Problemi correlati