Warum sehe ich THROW in einer C-Bibliothek?

Lesezeit: 5 Minuten

Benutzeravatar von mynk
Meink

Wenn ich das mache:
less /usr/include/stdio.h (was nur eine C-Bibliothek ist – nichts mit C++ zu tun)

Aha __THROW nach etlichen Funktionsdeklarationen. Außerdem heißt es in Kommentaren über einigen Funktionen: „Diese Funktion ist ein möglicher Abbruchpunkt und daher nicht mit gekennzeichnet __THROW‘Wozu das alles?

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

Bitte erkläre.

  • Welcher Compiler? Sieht für mich nach GCC aus. (Denken Sie daran, dass es keine “Standardbibliothek” gibt, daher ist es hilfreich anzugeben, welche Implementierung Sie verwenden.)

    – GManNickG

    21. März 2010 um 8:25 Uhr

  • Ahh, ich sehe, du hast glibc entdeckt 🙂

    – Tim Post

    21. März 2010 um 8:48 Uhr

Benutzeravatar von GManNickG
GManNickG

Dieser Header wird wahrscheinlich vom C- und C++-Compiler dieses Anbieters gemeinsam genutzt. Hast du was geschaut __THROW ist definiert als?

Ich vermute sowas in der Art:

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

Oder für tatsächliche Spezifikationen:

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

Wie Sie sehen können, wird es in einem C-Build zu nichts erweitert. In C++ tut es, was Sie erwarten. Dadurch können Anbieter dieselbe Datei wiederverwenden.


Nur um es pingelig zu machen, das ist nicht ganz richtig: “(was nur eine C-Bibliothek ist – nichts mit C++ zu tun)”

Die C++-Standardbibliothek enthält die Möglichkeit, die C-Standardbibliothek zu verwenden. Der eigentliche Header ist <cxxx> wo xxx ist der Name des C-Headers. Das heißt, den C-Header einzuschließen <stdlib.h> in C++ schon <cstdlib>. Es hat also mit C++ zu tun. 🙂

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

  • Danke deine Antwort ist sehr hilfreich.

    – Grijesh Chauhan

    10. März 2013 um 19:29 Uhr

  • Das Das THROW-Makro ist wie folgt definiert: wenn nicht definiert __cplusplus #define __THROW __attribute (( nicht werfen BLATT)). und wenn __cplusplus definiert ist, wird __THROW auf throw() erweitert. __LEAF ist wie folgt definiert: #define __LEAF , __leaf

    – Masalkhi

    25. Februar 2020 um 18:33 Uhr


  • Das stimmt, wenn GNUC definiert wurde, andernfalls ist __THROW in c und c++ umsonst zu verlängern

    – Masalkhi

    25. Februar 2020 um 18:50 Uhr

Benutzeravatar von PSkocik
PSkocik

Du kannst tun

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

um zu erfahren, worauf es sich tatsächlich ausdehnt.

Auf meinem System bekomme ich:

#define __THROW __attribute__ ((__nothrow__ __LEAF))

Das nicht werfen und Blatt Attribute sind unter beschrieben
https://gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/Common-Function-Attributes.html#Common-Function-Attributes
folgendermaßen:

Blatt

Blatt Aufrufe externer Funktionen mit diesem Attribut müssen nur per Return oder Ausnahmebehandlung zur aktuellen Übersetzungseinheit zurückkehren. Insbesondere darf eine Blattfunktion keine Callback-Funktionen aufrufen, die ihr von der aktuellen Kompilierungseinheit übergeben wurden, direkt von der Einheit exportierte Funktionen aufrufen oder in die Einheit longjmp eingeben. Blattfunktionen können immer noch Funktionen aus anderen Kompilierungseinheiten aufrufen und sind daher nicht unbedingt Blätter in dem Sinne, dass sie überhaupt keine Funktionsaufrufe enthalten. Das Attribut ist für Bibliotheksfunktionen vorgesehen, um die Datenflussanalyse zu verbessern. Der Compiler nimmt den Hinweis, dass alle Daten, die nicht der aktuellen Kompilierungseinheit entkommen, von der Blattfunktion nicht verwendet oder geändert werden können. Beispielsweise ist die sin-Funktion eine Blattfunktion, qsort jedoch nicht.

Beachten Sie, dass Blattfunktionen indirekt einen in der aktuellen Kompilierungseinheit definierten Signalhandler ausführen können, der statische Variablen verwendet. In ähnlicher Weise können Blattfunktionen bei aktiver verzögerter Symbolauflösung indirekte Funktionen aufrufen, deren Auflösungsfunktion oder Implementierungsfunktion in der aktuellen Kompilierungseinheit definiert ist und statische Variablen verwendet. Es gibt keine standardkonforme Möglichkeit, einen solchen Signal-Handler, eine Resolver-Funktion oder eine Implementierungsfunktion zu schreiben, und das Beste, was Sie tun können, ist, das Blattattribut zu entfernen oder alle solchen statischen Variablen als flüchtig zu markieren. Schließlich sollte bei ELF-basierten Systemen, die Symbolinterposition unterstützen, darauf geachtet werden, dass Funktionen, die in der aktuellen Kompilierungseinheit definiert sind, nicht unerwartet andere Symbole basierend auf dem definierten Standardmodus und den definierten Funktionstestmakros dazwischenschalten; andernfalls würde ein versehentlicher Rückruf hinzugefügt werden.

Das Attribut hat keine Auswirkung auf Funktionen, die innerhalb der aktuellen Übersetzungseinheit definiert sind. Dies soll ein einfaches Zusammenführen mehrerer Kompilierungseinheiten zu einer ermöglichen, beispielsweise durch Verwendung der Link-Time-Optimierung. Aus diesem Grund ist das Attribut auf Typen nicht erlaubt, um indirekte Aufrufe zu kommentieren.

nicht werfen

nothrow Das nothrow-Attribut wird verwendet, um den Compiler darüber zu informieren, dass eine Funktion keine Ausnahme auslösen kann. Zum Beispiel kann garantiert werden, dass die meisten Funktionen in der Standard-C-Bibliothek keine Ausnahme auslösen, mit den bemerkenswerten Ausnahmen von qsort und bsearch, die Funktionszeiger-Argumente annehmen.

Was __attribute__((nothrow)) bedeutet in C wird bei gcc beantwortet – wofür wird das Attribut nothrow verwendet? . Grundsätzlich ist es für die Zusammenarbeit mit C++-Code gedacht, und Sie können es verwenden, wenn die Funktion niemals auf C++-Code zurückruft, der Ausnahmen auslöst.

Benutzeravatar von Ioan
Ian

Um Ihre andere Frage zu “Diese Funktion ist ein möglicher Abbruchpunkt und daher nicht mit __THROW gekennzeichnet” zu beantworten: Hier geht es um Multithreading. Sie können einen Thread “abbrechen”, aber er wird nicht wirklich “abbrechen”, bis er einen Abbruchpunkt erreicht. Noch ein paar Infos: http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_cancel.3.html

  • Vielen Dank. Vollständig zu einem anderen Link geändert, der immer noch nützliche Informationen enthält.

    – Ian

    24. August 2012 um 13:51 Uhr

1408330cookie-checkWarum sehe ich THROW in einer C-Bibliothek?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy