Perché intercettare un'eccezione come riferimento a const?


84

Ho sentito e letto molte volte che è meglio catturare un'eccezione come riferimento a const piuttosto che come riferimento. Perché è:

try {
    // stuff
} catch (const std::exception& e) {
    // stuff
}

meglio di:

try {
    // stuff
} catch (std::exception& e) {
    // stuff
}

Risposte:


67

Hai bisogno:

  • un riferimento in modo da poter accedere all'eccezione polimorficamente
  • una const per aumentare le prestazioni e dire al compilatore che non modificherai l'oggetto

Quest'ultimo non è così importante come il primo, ma l'unica vera ragione per eliminare const sarebbe per segnalare che si desidera apportare modifiche all'eccezione (di solito utile solo se si desidera rilanciarla con contesto aggiunto a un livello superiore) .


1
"dì al compilatore che non modificherai l'oggetto": suppongo che potrebbe essere utile se stai passando l'oggetto come parametro a una chiamata di funzione.
Craig McQueen

1
cosa intendi con "accedi all'eccezione polimorficamente"?
mango

3
@mango presumibilmente significa essere in grado di chiamare una funzione virtuale (come std::exceptionla what()funzione di). Se prendi per valore, non puoi chiamare quella funzione e ottenere i dettagli dell'eccezione originale.
MM

11
ho guardato l'assembly prodotto da apple clang 7 e da gcc 5 (con ottimizzazione O3) e non vedo alcuna differenza tra const ref e non-const ref assembly. Quindi, immagino che non ci siano differenze nelle ottimizzazioni per gcc e apple clang
Vasiliy Soshnikov

2
Il compilatore può vedere facilmente quali oggetti si modificano e quali no ( SSA e propagazione costante). Serve una spiegazione migliore (o è un mito?).
rustyx

31

Non c'è fondamentalmente alcun motivo.

Gli oggetti eccezione risiedono nel proprio spazio di memoria quindi non devi preoccuparti di rilevare le eccezioni create nelle espressioni temporanee.

Tutto quello che stai facendo è promettente che non sarà possibile modificare l'oggetto eccezione, ma in quanto oggetti eccezione dovrebbe avere un'interfaccia immutabili , non c'è davvero nulla di pratico qui.

Tuttavia, potrebbe farti sentire caldo e accogliente quando lo leggi - è così per me!

Hanno il loro stack speciale, locale per i thread.
Disclaimer: Boost.Exception lo interrompe per fare cose funky e aggiungere dettagli sulle eccezioni, dopo la costruzione. Ma questo è hackery!


Potresti approfondire per favore Exception objects live in their own memory space? Hai una buona lettura da suggerire a riguardo?
Richard Dally

@LeFlou: Potrei indicarti lo standard, ma sarebbe un po 'fuorviante ritenere che "una buona lettura" ...: P
Lightness Races in Orbit

Sicuramente sì, sarebbe interessante saperne di più su questo da un punto di vista standard. Sto leggendo Technical Report on C ++ Performance , hai un documento più pertinente?
Richard Dally

@LeFlou: Beh, non c'è niente di più autorevole dello standard stesso ...
Gare di leggerezza in orbita

1
@RichardDally controlla C ++ Primer 5th , § 18.1.1 Excpetion Object. Dice L'oggetto eccezione risiede nello spazio, gestito dal compilatore, che è garantito per essere accessibile a qualsiasi cattura viene invocato. L'oggetto eccezione viene eliminato dopo che l'eccezione è stata completamente gestita.
Rick

5

Indica al compilatore che non chiamerai alcuna funzione che modifichi l'eccezione, il che potrebbe aiutare a ottimizzare il codice. Probabilmente non fa molta differenza, ma anche il costo per farlo è molto basso.


2

intendi modificare l'eccezione? in caso contrario, potrebbe anche essere const. stessa ragione per cui DOVRESTI usare const altrove (dico DOVREBBE perché in superficie non fa molta differenza, potrebbe aiutare i compilatori e anche aiutare i programmatori a usare correttamente il tuo codice e non fare cose che non dovrebbero)

gestori di eccezioni, possono essere specifici della piattaforma e possono inserire eccezioni in posti divertenti perché non si aspettano che cambino?


-1

Per lo stesso motivo per cui usi un const.


E per lo stesso motivo per cui preferire i riferimenti ai puntatori :-)
Dimitri C.

12
Semplice e disinvolto, ma non proprio una risposta.
Omnifarious
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.