Was bedeutet doppelten Unterstrich ( __const) bedeutet in C?
-
11-09-2019 - |
Frage
extern int ether_hostton (__const char *__hostname, struct ether_addr *__addr)
__THROW;
Ich fand die obige definition einer Funktion in /usr/include/netinet/ether.h auf einer Linux-box.
Kann jemand erklären, was der doppelten Unterstriche bedeuten vor const (Schlüsselwort), Adresse (id) und endlich __WERFEN.
Lösung
In C, Symbole, beginnend mit einem Unterstrich gefolgt von einem Großbuchstaben. oder ein weiterer Unterstrich sind reserviert für die Umsetzung.Sie als Nutzer von C sollten nicht schaffen, alle Symbole, die beginnen mit dem reservierten Sequenzen.In C++, die Einschränkung strenger;Sie können die Benutzer können nicht erstellen Sie ein symbol mit einem doppelten Unterstrich.
Gegeben:
extern int ether_hostton (__const char *__hostname, struct ether_addr *__addr)
__THROW;
Die __const
notation gibt es die Möglichkeit (eher unwahrscheinlich), dass ein compiler, der diesen code verwendet wird, unterstützt Prototyp-Notationen, aber nicht eine richtige Vorstellung von den C89-standard keyword const
.Die autoconf
Makros können immer noch überprüfen, ob der compiler hat die Arbeit unterstützen für const
;dieser code kann verwendet werden, mit einem gebrochenen compiler, der nicht unterstützt.
Die Verwendung von __hostname
und __addr
ist eine Schutzmaßnahme für Sie, die Benutzer der Kopf.Wenn Sie kompilieren mit GCC und der -Wshadow
option, der compiler wird Sie warnen, wenn Sie keine lokalen Variablen Schatten eine Globale variable.Wenn die Funktion verwendet wird gerade hostname
statt __hostname
, und wenn Sie hatte eine Funktion namens hostname()
, es wäre eine Verschattung.Durch die Verwendung von reservierten Namen der Implementierung, gibt es keinen Konflikt mit Ihren legitimen code.
Die Verwendung von __THROW
bedeutet, dass der code kann unter bestimmten Umständen kann erklärt werden mit irgendeiner Art von "throw-Spezifikation".Dies ist nicht standard-C;es ist mehr wie C++.Aber der code kann verwendet werden mit einem C-compiler so lange, wie man den Header (oder der compiler selbst) definiert __THROW
zu entleeren, oder um einige compiler-spezifische Erweiterung der standard-C-syntax.
Abschnitt 7.1.3 der C-standard (ISO 9899:1999), sagt:
7.1.3 Reserved identifiers
Jeder header deklariert oder definiert alle IDS aufgelistet in der zugeordneten Ziffer, und Optional deklariert oder definiert Bezeichner aufgeführt in den damit verbundenen zukünftigen Bibliothek Richtungen ABS und Bezeichner, die immer vorbehalten entweder für die Verwendung oder für die Verwendung als Datei Gültigkeitsbereich von Bezeichnern.
— Alle Bezeichner, die mit einem Unterstrich beginnen und entweder einen Großbuchstaben oder ein anderes Unterstrich sind immer reserviert für jegliche Nutzung.
— Alle Bezeichner, die mit einem Unterstrich beginnen, sind immer reserviert für die Verwendung als Bezeichner mit dem Datei-Bereich sowohl in der normalen und der tag-name-spaces.
— Jedes makro-Namen in einem der folgenden Ziffern (einschließlich der zukünftigen Bibliothek Richtungen) ist reserviert für den Einsatz als angegeben, wenn alle zugehörigen Header enthalten ist;sofern nicht ausdrücklich anders angegeben (siehe 7.1.4).
— Alle Bezeichner mit externer Verknüpfung in eine der folgenden Ziffern (einschließlich der zukünftige Bibliothek Richtungen) sind immer reserviert für die Verwendung als Bezeichner mit externer Verknüpfung.154)
— Jeder Bezeichner mit Datei Bereich aufgeführt in den folgenden Absätzen (einschließlich der zukünftige Bibliothek Richtungen) ist reserviert für den Einsatz als einen makro-Namen und einem Bezeichner mit Datei Umfang in der gleichnamigen Platz, wenn alle zugehörigen Header enthalten ist.
Keine andere Identifikatoren sind vorbehalten.Wenn das Programm erklärt oder definiert einen Bezeichner in einem Kontext, in dem es vorbehalten ist (anders als zulässig 7.1.4), oder definiert einen reserved Bezeichner als Namen eines Makros, das Verhalten ist undefiniert.
Wenn das Programm entfernt (mit
#undef
) makro-definition eines Bezeichners in der ersten Gruppe oben aufgeführt, ist das Verhalten undefiniert.Fußnote 154) Die Liste der reservierten Bezeichner mit externer Verknüpfung enthält
errno
,math_errhandling
,setjmp
, undva_end
.
Siehe auch Was sind die Regeln über die Verwendung von Unterstrich in einer C++ - Bezeichner;viele der gleichen Regeln gelten sowohl für C und C++, wenn der embedded-double-underscore-Regel ist in C++ nur, wie bereits oben in dieser Antwort.
Andere Tipps
Namen mit doppelten führende Unterstriche sind reserviert für die Verwendung durch die Umsetzung.Dies muss nicht unbedingt bedeuten Sie sind intern per se, obwohl Sie Häufig sind.
Die Idee ist, Sie sind nicht erlaubt zu verwenden alle Namen beginnend mit __
, also die Umsetzung ist frei, Sie zu verwenden in Orten wie makro-Erweiterungen, oder die Namen der syntax-Erweiterungen (z.B. __gcnew
ist nicht Teil von C++, aber Microsoft kann hinzufügen, dass es C++/CLI sicher, dass keine bestehenden code sollte so etwas wie int __gcnew;
dass es aufhören würde zu kompilieren).
Finden Sie heraus, was diese spezifischen Erweiterungen bedeuten, D. H. __const
Sie müssen Lesen Sie die Dokumentation für Ihre spezielle compiler/Plattform.In diesem Fall sollten Sie wahrscheinlich erwägen den Prototyp in der Dokumentation (z.B. http://www.kernel.org/doc/man-pages/online/pages/man3/ether_aton.3.html) die Funktion s-Schnittstelle und ignorieren Sie die __const
und __THROW
Dekorationen, erscheint im eigentlichen header.
Per Konvention in einigen Bibliotheken, bedeutet dies, dass ein bestimmtes symbol ist für den internen Gebrauch und sind nicht als Teil der öffentlichen API der Bibliothek.
Der Unterstrich in __const bedeutet, dass dieses Schlüsselwort ist eine compiler-Erweiterung, und es ist nicht portabel (Das const-Schlüsselwort Hinzugefügt wurde C bei einer späteren revision, 89 glaube ich).Das __WERFEN ist auch eine Art von Erweiterung, nehme ich an, dass es wird definiert, um einige __Attribut__(etwas), wenn gcc verwendet wird, bin mir Aber nicht sicher und zu faul, um zu überprüfen.Die __addr bedeuten kann alles, was der Programmierer wollte es zu bedeuten, Es ist nur ein name.