2010-02-24 6 views
5

lettura this Wikipedia articolo ha sottolineato da uno dei repliers alla seguente domanda:L'ottimizzazione del valore di ritorno causa un comportamento indefinito?

C++ Copy constructor, temporaries and copy semantics

mi sono imbattuto in questa linea

A seconda del compilatore, e le impostazioni del compilatore, il programma risultante può visualizzare una delle seguenti uscite:

Questo non si qualifica per comportamento non definito? So che l'articolo dice Depending on the compiler and settings ma voglio solo chiarirlo.

+3

Esiste l'implementazione, in cui l'implementatore del compilatore deve documentare il comportamento, quindi qui non è specificato, il che significa che il compilatore può fare tutto ciò che vuole purché il "comportamento osservabile" rimanga lo stesso. Poi c'è un comportamento indefinito, il che significa che hai inserito uno stato nel programma in cui la sua esecuzione non è più definita. RVO è un caso in cui il comportamento osservabile è autorizzato a cambiare. – GManNickG

risposta

12

No, non è un comportamento non definito. Il comportamento non definito ha una definizione specifica nello standard (principalmente: "comportamento, come potrebbe sorgere in seguito all'uso di un costrutto errato di programma o di dati errati, per il quale questo Standard Internazionale non impone alcun requisito.") In questo caso, il comportamento non è specificato, ma non indefinito.

La differenza è che qualsiasi esecuzione di qualsiasi cosa con comportamento non definito rende indefinito tutto il comportamento del programma (ad esempio, qualsiasi cosa può accadere). Con questo particolare comportamento non specificato, può accadere solo una delle due cose: o il costruttore della copia viene eseguito, oppure no.

+0

Ricordo che ero abbastanza confuso quando iniziai tra: non definito, non specificato e definito dall'implementazione. Spiegazione molto buona e concisa. –

2

No. Il comportamento è definito come uno degli output nell'elenco. Il comportamento indefinito include i demoni che volano fuori dal tuo naso.

Vedi: Nasal Demons

1

undefined behavior è molto diverso da implementation defined behavior, che è ciò che è coinvolto qui.

+4

Non è realmente definito dall'implementazione - ciò richiederebbe l'implementazione per documentare ciò che accade, che non è richiesto in questo caso. –

0

Dipende da cosa si intende per indefinito. Credo quello che altri hanno detto qui - dalla definizione che il documento standard usa. Ma so anche che quando qualcuno dice "o questo o quello, non ti sto dicendo quale" Penso che sia un comportamento indefinito.

Non è un grosso problema, tuttavia, poiché non dovrebbe mai causare un errore. Quando definisci determinati metodi, ci si aspetta che li definiscano seguendo particolari convenzioni: è una specie di contratto implicito tra te, il compilatore e le persone che useranno e manterranno il tuo codice.

In questo caso, sia che si ottenga un costrutto di copia ecc. O il comportamento ottimizzato, l'effetto dovrebbe essere lo stesso - il chiamante riceve il valore desiderato. Se il tuo costruttore di copie sta stampando "Hello World!" o ha altri effetti collaterali inappropriati, non sta implementando il comportamento previsto per un costruttore, quindi l'errore è tuo per aver violato il contratto.

+0

+1 per dire degli effetti _ _ che potrebbero non essere eseguiti in modo invisibile a causa di questa ottimizzazione :) Se si tratta di una dichiarazione di stampa che stai guardando con impazienza sul terminale, puoi prenderlo comunque; mentre qualcosa di più silenzioso, ad esempio, passare un messaggio a un altro oggetto quando la costruzione avviene, non accadrà e sarà difficile da catturare. – legends2k

+0

Quindi posso dedurre che, indipendentemente dal tipo di costruttore (sia esso predefinito, copia, ecc.), Non dovrei fare qualcosa di specifico oltre all'inizializzazione dei membri? – legends2k

+0

@ legends2k: sì. Lo standard consente di elidere le chiamate del costruttore di copie quando si torna da una funzione, il che significa che il proprio codice non deve cercare di fare affidamento sugli effetti collaterali nei costruttori di copia. – UncleBens