2013-04-06 13 views
22

Ho le funzioni C++ che voglio dichiarare usando extern "C" anche se sono chiamate solo in codice C++. Sì, so che è strano ma è qualcosa che vorrei fare per coerenza dal momento che abbiamo mescolato dichiarazioni C e C++. Voglio solo assicurarmi che dichiarare una funzione C++ come extern "C" non influenzi il comportamento del lancio.Le funzioni C++ possono essere contrassegnate come lancio "C" di Extern?

Sarebbe sembrare qualcosa di simile:

extern "C" void foo() {throw exception;} 

int bar() 
{ 
    try 
    { 
     foo(); 
    } catch (exception e) { return 1; } 
} 
+0

[domanda correlata] (http://stackoverflow.com/questions/4695741/is-there-a-gcc-option-to-assume-all-extern-c-functions-cannot-propagate-except). –

+1

Le risposte affermano che si sta invocando un comportamento non definito se un'eccezione viene generata dal codice C++ nell'effettivo codice C (che non saprebbe cosa fare con un'eccezione). Penso che sia corretto, ma stai chiedendo di chiamare le funzioni "extern" C "' da C++ o da C?Se li chiami da C++ (e mai da C), c'è l'inevitabile domanda "perché le funzioni 'extern" C "' se non vengono mai chiamate da un'altra lingua? ", Ma penso che semplicemente chiamano le funzioni C++ con 'extern" C "' da C++ significa che non vi è alcun confine linguistico attraversato e quindi nessun comportamento indefinito. –

+0

Grazie a tutti coloro che hanno contribuito a rispondere a questo. Se ho capito bene, la risposta definitiva alla mia domanda era questa: la "C" esterna non cambia il modo in cui viene gestita un'eccezione. Tuttavia, lanciare un'eccezione che non viene catturata e attraversa i limiti del linguaggio ha un comportamento indefinito. –

risposta

8

"Le funzioni C++ possono essere contrassegnate come Extern" C "?"

, nel senso che né la lingua né il compilatore impediranno di farlo.

, nel senso che se si lancia, sarebbe un comportamento non definito, in quanto l'eccezione C++ supera i limiti del linguaggio.

In pratica: non farlo. Cattura l'eccezione e tradurla in un codice di errore o in un linguaggio comprensibile per l'altra lingua.

Quindi la linea di fondo è: NON eccezione per le funzioni contrassegnate come extern "C".

+0

Potrebbe tecnicamente essere un "comportamento non specificato", ma in entrambi i casi: non buono. –

+0

Lo standard C++ dice veramente che è un comportamento indefinito quando un'eccezione supera i limiti del linguaggio? Ho difficoltà a credere che, poiché lo standard C++ si occupa solo di C++ e C++, e "i limiti del linguaggio" è al di fuori dell'ambito di C++. Suppongo che se un'eccezione C++ viene lanciata in una lingua che non supporta eccezioni C++, l'eccezione viene propagata solo finché non viene rilevata da qualche parte o il programma viene terminato. Ma ovviamente dipende dal sistema operativo e dal compilatore. – user1610015

+2

Non si può dire "SÌ" quando è "comportamento non definito". Quando invochi "comportamento indefinito" il tuo codice è fondamentalmente rotto. –

0

Ecco risposta alla vostra domanda: http://yosefk.com/c++fqa/mixing.html#fqa-32.6

In sostanza non sarà in grado di prenderlo. (ma perché non lo compilerete e provate? :))

+15

"compila e prova" non è mai una buona idea per le lingue con un comportamento indefinito. –

+4

Ma potrebbe portare a fare false ipotesi sul comportamento del codice quando in realtà non dovresti assumere nulla, perché non è definito e un compilatore potrebbe fare qualsiasi cosa con esso. –

+5

@PiotrJaszkowski: Potrebbe non distruggere l'universo, ma i draghi vomiteranno il tuo naso. Cercando un comportamento indefinito è inutile che non impari nulla dato che il test non ha significato. –

2

verrà compilato ma è un comportamento non definito da eseguire dalla funzione contrassegnata come avente collegamento C. C non ha eccezioni, quindi in generale dovresti solo restituire un codice di errore e/o fornire una funzione che restituisca le informazioni sull'ultimo errore.

#include <exception> 
extern "C" void foo() {throw std::exception();} 

compila ben

4

Per GCC the answer seems inconclusive.

Il MSVC documentation, tuttavia è relativamente chiaro sul tema:

  • /EHa e /EHs ... dice al compilatore di ritenere che le funzioni dichiarate come extern "C" può generare un'eccezione.
  • /EHsc ... dice al compilatore di ritenere che le funzioni dichiarate come extern "C" non gettare un C++ un'eccezione

Così per Visual-C++ dipende dalle opzioni del compilatore se si ottiene comportamento definito .

+1

+1, ma hai perso la risposta gcc in uno dei commenti collegati: '-fexceptions'. Da gcc docs: "... potrebbe essere necessario abilitare questa opzione durante la compilazione del codice C che deve interoperare correttamente con gestori di eccezioni scritti in C++". – EML

Problemi correlati