2010-03-21 4 views
28

Wenn ich tun: less /usr/include/stdio.h (die nur eine C-Bibliothek ist - nichts mit C zu tun ++)Warum sehe ich THROW in einer C-Bibliothek?

ich __THROW nach ganz wenigen Funktionsdeklarationen zu sehen. Auch Kommentare über ein paar Funktionen sagen, dass 'Diese Funktion ist ein möglicher Abbruch Punkt und daher nicht markiert mit __THROW' Was ist das alles?

throw ist für Ausnahmebehandlung gedacht ... aber soweit ich weiß, bietet C keine Unterstützung dafür.

Bitte erläutern.

+1

Welcher Compiler? Sieht für mich wie GCC aus. (Denken Sie daran, dass es keine "Standardbibliothek" gibt. Daher ist es hilfreich, die Implementierung anzugeben, die Sie verwenden.) – GManNickG

+1

Ahh, ich sehe, Sie haben glibc entdeckt :) –

Antwort

34

Dieser Header wird wahrscheinlich zwischen dem C- und C++ - Compiler für diesen Anbieter freigegeben. Hast du geschaut, was __THROW als definiert ist?

Ich vermute, so etwas wie:

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

Oder tatsächlichen Spezifikationen:

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

Wie Sie in einer C-Build sehen kann, dehnt es sich so gut wie nichts. In C++ macht es das, was Sie erwarten. Dies ermöglicht es Herstellern, dieselbe Datei wiederzuverwenden.


Nur nitpick, dies nicht ganz richtig ist: "(die nur eine C-Bibliothek ist - nichts mit C zu tun ++)"

Die C++ Standard-Bibliothek beinhaltet die Fähigkeit, das zu verwenden, C Standardbibliothek. Der eigentliche Header ist <cxxx>, wobei xxx der C-Header-Name ist. Das heißt, um den C-Header <stdlib.h> in C++ einzuschließen, tun Sie <cstdlib>. Es hat also mit C++ zu tun. :)

Deshalb sehen Sie den Code, den Sie tun. Duplizieren der Header für zwei verschiedene Sprachen wäre ein Albtraum für Wartung und Sauberkeit.

+0

Vielen Dank Ihre Antwort ist sehr hilfreich. –

3

Um Ihre andere Frage zu beantworten "Diese Funktion ist ein möglicher Abbruch Punkt und daher nicht markiert mit __THROW": Dies betrifft Multi-Threading. Sie können einen Thread "abbrechen", aber er wird nicht "abbrechen", bis er einen Abbruchpunkt erreicht. Einige weitere Informationen: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html

+0

Link ist kaputt. –

+0

Danke. Wurde komplett zu einem anderen Link geändert, der immer noch nützliche Informationen enthält. – Ioan

2

können Sie tun

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

zu lernen, was es tatsächlich erweitert.

Auf meinem System, die ich erhalten:

#define __THROW __attribute__ ((__nothrow__ __LEAF)) 

Die nothrow und Blatt Attribute bei https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes werden wie folgt beschrieben:

Blatt

leaf Aufrufe an externe Funktionen mit diesem Attribut müssen die aktuelle Übersetzungseinheit nur per Rückgabe oder durch Ausnahmebehandlung an zurückgeben. Insbesondere ist es einer Blattfunktion nicht erlaubt, Rückruffunktionen Funktionen aufzurufen, die von der aktuellen Kompilierungseinheit an sie übergeben werden, direkt Anruffunktionen, die von der Einheit exportiert wurden, oder longjmp in die Einheit. Leaf Funktionen können immer noch Funktionen aus anderen Kompilierungseinheiten und aufrufen, daher sind sie nicht unbedingt in dem Sinne Blatt, dass sie überhaupt keine Funktionsaufrufe enthalten. Das Attribut ist für die Bibliotheksfunktionen vorgesehen, um die Datenflussanalyse zu verbessern. Der Compiler nimmt den Hinweis, dass alle Daten, die nicht der aktuellen Kompilierungseinheit entgehen, nicht verwendet werden können oder durch die Blattfunktion modifiziert werden. Zum Beispiel ist die sin-Funktion eine Blatt- -Funktion, aber qsort ist nicht.

Beachten Sie, dass Blattfunktionen indirekt einen Signal-Handler in der aktuellen Kompilierungseinheit ausführen können, die statische Variablen verwendet. Ähnlich, wenn faule Symbolauflösung wirksam ist, können Blattfunktionen indirekte Funktionen aufrufen, deren Resolverfunktion oder Implementierungsfunktion in der aktuellen Kompilierungseinheit definiert ist und statische Variablen verwendet. Es gibt keine standardkonforme Möglichkeit, einen solchen Signalhandler, Resolver-Funktion oder Implementierungsfunktion zu schreiben, und das beste, was Sie tun können, ist das Leaf-Attribut zu entfernen oder markieren Sie alle diese statischen Variablen volatile. Schließlich sollte für ELF-basierte Systeme, die das Symbol unterstützen, darauf geachtet werden, dass Funktionen, die in der aktuellen Kompilierungseinheit definiert sind, nicht unerwartet andere Symbole auf der Grundlage des definierten Standardmodus und der definierten Feature-Test-Makros einfügen; andernfalls würde ein versehentlicher Rückruf hinzugefügt werden.

Das Attribut hat keine Auswirkungen auf Funktionen, die in der aktuellen Kompiliereinheit definiert sind. Dies ermöglicht das einfache Zusammenführen mehrerer Kompiliereinheiten zu einem, beispielsweise unter Verwendung der Verknüpfungszeit Optimierung. Aus diesem Grund ist das Attribut für Typen nicht erlaubt indirekte Aufrufe annotieren.

nothrow

nothrow The nothrow Attribut verwendet wird, um den Compiler zu informieren, dass eine Funktion nicht eine Ausnahme auslösen kann. Zum Beispiel können die meisten Funktionen in der Standard-C-Bibliothek garantiert werden, keine Ausnahme zu werfen mit die bemerkenswerten Ausnahmen von qsort und bsearch, die Funktionszeiger Argumente nehmen.

Was __attribute__((nothrow)) in C bedeutet bei gcc - what is attribute nothrow used for? beantwortet. Grundsätzlich ist es für die Zusammenarbeit mit C++ - Code, und Sie können es verwenden, wenn die Funktion nicht immer wieder auf Ausnahme-C++ - Code zurückrufen wird.

Verwandte Themen