Specifiche di eccezione quando derivano da std :: exception in C ++ 11

Ho una class di eccezione come segue:

#include  struct InvalidPathException : public std::exception { explicit InvalidPathException() {} const char* what() const; }; const char* InvalidPathException::what() const { return "Path is not valid"; } 

Durante la compilazione in GCC 4.4 con -Wall -std = c ++ 0x

errore: identificatore di lancio più lento per ‘const const virtuale * InvalidPathException :: what () const’

errore: sovrascrivere ‘virtual const char * std :: exception :: what () const throw ()’

Giustissimo, dato che sto sovrascrivendo il metodo what() std::exception che ha in effetti un identificatore di eccezione throw() . Ma come spesso verrà informato , non dovremmo usare gli specificatori di eccezione. E a quanto ho capito, sono deprecati in C ++ 11 , ma evidentemente non ancora in GCC con -std = c ++ 0x.

    Quindi sarei interessato all’approccio migliore per ora. Nel codice che sto sviluppando mi interessa le prestazioni e quindi mi preoccupo del sovraccarico spesso menzionato di throw() , ma in realtà questo overhead è così grave? Ho ragione nel pensare che ne soffrirei solo quando viene chiamato what() , che sarebbe solo dopo che un’eccezione di questo tipo è stata lanciata (e allo stesso modo per gli altri metodi ereditati da std :: exception that all have throw() specificatori )?

    In alternativa, c’è un modo per ovviare a questo errore dato da GCC?

    Le specifiche del throw vuoto sono utili, in quanto consentono effettivamente ottimizzazioni del compilatore sul sito del chiamante, come sa Wikipedia (non ho una quotazione tecnica a portata di mano).

    E per ragioni di opportunità di ottimizzazione, le specifiche di nothrow non sono deprecate nello standard imminente, semplicemente non assomigliano più a throw () ma sono chiamate noexcept . Bene, sì, e funzionano in modo leggermente diverso.

    Ecco una discussione di noexcept che noexcept anche perché le tradizionali nothrow-specificano le ottimizzazioni prohobit sul sito del callee.

    Generalmente, si paga per ogni specifica di throw si ha, almeno con un compilatore completamente conforms, che GCC ha, a questo proposito, apparentemente non sempre stato. Le specifiche del throw devono essere verificate in fase di esecuzione, anche quelle vuote. Questo perché se viene sollevata un’eccezione che non è conforms alle specifiche di throw , lo sbobinamento dello stack deve avvenire all’interno di quel frame di stack (quindi è necessario un codice per questo oltre al controllo di conformità) e quindi std::unexpected deve essere chiamato. D’altra parte, puoi potenzialmente risparmiare tempo / spazio per ogni specifica di throw vuoto in quanto il compilatore può fare più ipotesi quando chiama quella funzione. Escludo dicendo che solo un profiler può darti la risposta definitiva se il tuo codice particolare soffre o migliora ( vuote !).

    Come soluzione alternativa al tuo problema reale, può il seguente lavoro?

    • Introduci #define NOTHROW throw () e #define NOTHROW throw () per what e altre cose della tua eccezione.
    • Quando GCC implementa noexcept , ridefinisci NOTHROW .

    Aggiornare

    Come note @James McNellis, throw () sarà compatibile con le versioni successive. In tal caso, ti suggerisco di usare throw () dove devi e, a parte questo, in caso di dubbio, profilo.