2010-03-21 20 views
28

Quando faccio: less /usr/include/stdio.h (che è solo una libreria C - niente a che fare con il C++)Perché vedo THROW in una libreria C?

vedo __THROW dopo un bel paio di dichiarazioni di funzioni. Inoltre, i commenti sopra alcune funzioni dicono che 'Questa funzione è un possibile punto di cancellazione e quindi non contrassegnata con __THROW' A cosa serve tutto questo?

throw è pensato per la gestione delle eccezioni ... ma per quanto ne so, C non fornisce alcun supporto per questo.

Spiegare per favore.

+1

Quale compilatore? Sembra GCC per me. (Tieni presente che non esiste la "libreria standard", quindi è utile specificare quale implementazione usi.) – GManNickG

+1

Ah, vedo che hai scoperto glibc :) –

risposta

34

Questa intestazione è probabilmente condivisa tra il compilatore C e C++ per quel fornitore. Hai visto cosa è definito __THROW?

ho il sospetto qualcosa di simile a:

#ifdef __cplusplus 
    #define __THROW throw() 
#else 
    #define __THROW 
#endif 

che per le caratteristiche effettive:

#ifdef __cplusplus 
    #define __THROW(x) throw(x) 
#else 
    #define __THROW(x) 
#endif 

Come si può vedere, in una build C, si espande per niente. In C++, fa quello che ti aspetti. Ciò consente ai fornitori di riutilizzare lo stesso file.


Basta essere pignoli, questo non è del tutto vero: "(che è solo una libreria C - niente a che fare con il C++)"

La libreria standard C++ include la possibilità di utilizzare il C libreria standard. L'intestazione effettiva è <cxxx> dove xxx è il nome dell'intestazione C. Cioè, per includere l'intestazione C <stdlib.h> in C++, fai <cstdlib>. Quindi ha a che fare con C++. :)

Ecco perché vedi il codice che fai. Duplicare l'intestazione per due lingue diverse sarebbe un incubo per la manutenzione e la pulizia.

+0

Grazie, la tua risposta è molto utile. Il collegamento –

3

Per rispondere alla tua altra domanda relativa a "Questa funzione è un possibile punto di annullamento e quindi non contrassegnata con __TROW": si tratta di multi-threading. È possibile "annullare" una discussione, ma in realtà non "annulla" fino a quando non raggiunge un punto di annullamento. Alcune ulteriori informazioni: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html

+0

è rotto. –

+0

Grazie. Modificato su un altro collegamento che fornisce comunque informazioni utili. – Ioan

2

Si può fare

cpp -include stdlib.h -dM /dev/null |grep '#define __THROW ' 

per imparare che cosa si espande sino a.

Sul mio sistema, ottengo:

#define __THROW __attribute__ ((__nothrow__ __LEAF)) 

Il nothrow e foglia attributi sono descritti in https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes come segue:

foglia

leaf Le chiamate a funzioni esterne con questo attributo devono restituire a l'unità di compilazione corrente solo mediante restituzione o gestione delle eccezioni. In particolare, una funzione foglia non è autorizzata a richiamare le funzioni di callback trasmesse dall'unità di compilazione corrente, direttamente le funzioni di chiamata esportate dall'unità o longjmp nell'unità. Le funzioni foglia possono ancora chiamare le funzioni da altre unità di compilazione e quindi non sono necessariamente foglia nel senso che non contengono nessuna chiamata di funzione . L'attributo è destinato alle funzioni di libreria per migliorare l'analisi del flusso di dati. Il compilatore fa riferimento al fatto che non è possibile utilizzare i dati che non sfuggono all'attuale unità di compilazione o modificati dalla funzione foglia. Ad esempio, la funzione sin è una funzione foglia , ma qsort non lo è.

Si noti che le funzioni foglia potrebbero indirettamente eseguire un gestore di segnale definito nell'unità di compilazione corrente che utilizza variabili statiche. Allo stesso modo, quando è attiva la risoluzione del simbolo pigro, le funzioni foglia possono richiamare le funzioni indirette la cui funzione resolver o funzione di implementazione è definita nell'unità di compilazione corrente e utilizza variabili statiche. Non esiste un modo conforme allo standard per scrivere un gestore di segnali di questo tipo, la funzione di implementazione o la funzione di implementazione e il meglio che si può fare è rimuovere l'attributo leaf o contrassegnare tutte le variabili statiche volatile. Infine, per i sistemi basati su ELF che supportano l'interposizione del simbolo , occorre prestare attenzione che le funzioni definite nell'unità di compilazione corrente non interpongono in modo imprevisto altri simboli in base alla modalità standard definita e alle macro di test delle funzioni definite; altrimenti verrà aggiunto un callback involontario.

L'attributo non ha effetto sulle funzioni definite nell'unità di compilazione corrente. Ciò consente di unire facilmente più unità di compilazione in una, utilizzando l'ottimizzazione di link-time. Per questo motivo l'attributo non è ammesso sui tipi di chiamate indirette con annotazione .

nothrow

nothrow L'attributo nothrow viene utilizzato per informare il compilatore che una funzione non può generare un'eccezione. Ad esempio, la maggior parte delle funzioni nella libreria C standard non può generare un'eccezione con le notevoli eccezioni di qsort e bsearch che accettano gli argomenti del puntatore di funzione .

Che cosa significa __attribute__((nothrow)) in C viene risposto a gcc - what is attribute nothrow used for?. Fondamentalmente, è per la cooperazione con il codice C++, e puoi usarlo se la funzione non richiamerà mai il codice C++ che genera eccezioni.

Problemi correlati