2010-02-08 13 views
7

Anni fa credevo che C fosse assolutamente puro rispetto a C++ perché il compilatore non poteva generare alcun codice che non si poteva prevedere. Ora credo che gli esempi contrari includano la parola chiave volatile e le barriere della memoria (nella programmazione multiprocessore o driver di periferica per dispositivi hardware mappati in memoria, dove il linguaggio di assemblaggio semplice sarebbe ancora più puro delle ottimizzazioni di un compilatore C).Modi per creare accidentalmente oggetti temporanei in C++?

Al momento sto cercando di enumerare le cose imprevedibili che un compilatore C++ può fare. La lamentela principale che mi viene in mente riguardo al C++ è che il compilatore istanzia implicitamente degli oggetti temporanei, ma credo che questi casi possano tutti essere previsti. I casi che sto pensando di sono:

  • quando una classe definisce un costruttore di copia di un tipo diverso da sé, senza utilizzare la parola chiave explicit
  • Quando una classe definisce un operatore di conversione di overload: operator()
  • quando una funzione accetta un oggetto per valore invece che con riferimento
  • quando una funzione restituisce un oggetto per valore invece che con riferimento

sono la re altri?

+0

+1: interessante quando si tratta di sistemi embedded. – jldupont

+3

Questi sono tutti definiti nello standard e quindi possono essere previsti - quelli che non possono essere previsti sono comportamenti non definiti – Mark

+1

In C si hanno conversioni implicite (cast), quindi non direi che è "puro". – Manuel

risposta

2

Suppongo che "imprevedibile" significhi "qualcosa in accordo con lo standard ma diverso da quello che il programmatore si aspetta quando scrive il codice", giusto?

Immagino che si possa vedere dal codice in cui gli oggetti vengono istanziati o copiati, anche se forse non è ovvio. Potrebbe essere difficile da capire però.

Alcune cose vengono implementate in determinati modi dai fornitori di compilatori (tutti?), Ma potrebbero essere eseguite in modo diverso. Ad esempio, l'associazione tardiva (chiamata anche un metodo virtuale sovraccarico) viene solitamente implementata utilizzando i puntatori di funzione in background. Questo è forse il modo più veloce per farlo, ma suppongo che potrebbe essere fatto in modo diverso e che sarebbe inaspettato. Non conosco alcun compilatore sebbene lo faccia in modo diverso.

Un sacco di cose è inaspettato nel senso che il C++ è eccessivamente complesso - quasi nessuno capisce il linguaggio completo. Quindi inaspettato dipende anche dalle tue conoscenze.

+0

+1 per una buona analisi di ciò che sembra essere il problema nel comprendere la domanda. –

2

12,2 oggetti temporanei

1 Temporaries di tipo classe sono creati in diversi contesti: binding un rvalue ad un riferimento (8.5.3), restituendo un rvalue (6.6.3), una conversione che crea un rvalue (4.1, 5.2.9, 5.2.11, 5.4), gettando un un'eccezione (15.1), entrando in un gestore (15.3), e in alcuni inizializzazioni (8.5).

4 Ci sono due contesti in cui provvisori vengono distrutti in un punto diverso rispetto all'estremità del fullexpression.

In effetti suggerisco di dare un'occhiata a tutto il 12.2

Al momento sto cercando di elencare le cose imprevedibili un compilatore C++ può fare. La lamentela principale che mi viene in mente riguardo al C++ è che il compilatore implicherà implicitamente istanzia oggetti temporanei, ma io credo che questi casi possano essere tutti previsti.

Il compilatore non crea temporary implicitamente - obbedisce allo standard. A meno che, naturalmente, non invochi comportamenti indefiniti. Si noti che esiste qualcosa chiamato copy-elision e ottimizzazione del valore di ritorno che può effettivamente ridurre il numero di provvisori che altrimenti verrebbero creati.

Problemi correlati