2010-08-12 10 views
5

Ho sentito dire che lanciare eccezioni in/da una libreria C++ potrebbe essere potenzialmente pericoloso, in particolare con le DLL, e in particolare se il codice chiamante e la libreria sono compilati con compilatori diversi. C'è qualche verità in questo? È sicuro finché rimango nelle librerie statiche? Nota che non sto parlando solo dell'uso interno delle eccezioni nella libreria, ma voglio inserirli anche nel codice chiamante :)Non è sicuro generare eccezioni da librerie C++ collegate in modo statico?

Giusto per chiarire: Dire che ho una libreria statica compilata che definisce la classe Foo come questo:

class Foo 
{ 
public: 
    // Constructor 
    Foo() 
    { 
     /* ... Do stuff ... */   
     if (stuffwentwrong) 
      throw(123); // We throw an integer error code (to make it simple) 
    } 
}; 

E qualche ragazzo usa in questo modo:

try 
{ 
    Foo foo_object; 
} 
catch (int i) 
{ 
    std::cout << "Oh bum. Code: " << i; 
} 

Vorrei che sia sicuro?

+0

Ci sono stati problemi (circa 15 anni fa) questi sono stati risolti (a meno che non si sta facendo le cose funky come il caricamento dinamico/scarico DLL tutto da solo). Se stai semplicemente usando una DLL, dovresti stare bene. –

risposta

3

e in particolare se il codice chiamante e la biblioteca sono compilati con diversi compilatori

In genere non può mescolare diversi compilatori C++ che non hanno ABI compatibili. Ad esempio, non è possibile generare un'eccezione dalla libreria compilata con MSVC e provare a rilevare lo con GCC.

In caso contrario, in genere non si verificano problemi.

Piccola nota:

MSVC ha diversi modelli di eccezione incompatibili, non li mescolare.

+0

ci sono molte altre sottigliezze che lo rendono comunque pericoloso in generale. Ad esempio, se la DLL è compilata con una versione diversa del CRT, verrai avvitato (ad esempio, debug vs. release, o multithreading vs. single threaded).Anche il CRT memorizza determinati stati a livello di modulo, non a livello di processo (ad esempio hModule o informazioni di tracciamento della memoria), quindi quando si trasmettono oggetti dipendenti da CRT attraverso i confini della DLL, tutte queste cose possono andare fuori sincrono. E gli errori sono in fase di esecuzione, e possono essere molto sottili/grattacapi. In generale, evita questo. – tenfour

0

L'esempio che hai fornito dovrebbe funzionare correttamente, tuttavia con le DLL, se ti capita di lanciare un'eccezione allocata, si bloccherà se il consumer della DLL tenta di liberare l'eccezione allocata nell'heap.

3

Rispetto al GCC, c'è almeno un caso in cui la cattura eccezioni GCC generati condiviso le librerie possono essere problematici, vale a dire quando dimenticando di esportare il tipo in grado throw dalla libreria condivisa quando la visibilità simbolo è "hidden" per impostazione predefinita. La pagina GCC Visibility Wiki fornisce informazioni dettagliate sul problema e su come prevenirlo.

Non sono sicuro che le DLL di Windows abbiano problemi simili, ma sembra probabile.

1

Gotcha generale quando si tratta di DLL ed eccezioni:

non implementano la linea eccezioni di classe nell'intestazione. Si finirà con vtables duplicati e informazioni RTTI, con il risultato che le eccezioni non vengono catturate nel codice usando (a causa della duplicazione, l'eccezione è considerata di un altro tipo).

I dettagli:

http://marcmutz.wordpress.com/2010/08/04/fun-with-exceptions/

Problemi correlati