variable - jsf coding standard c++




Welche Regeln gelten für die Verwendung eines Unterstrichs in einer C++-ID? (4)

Die Regeln (die sich in C ++ 11 nicht geändert haben):

  • In jedem Bereich reserviert, einschließlich zur Verwendung als Implementierungs-Makros:
    • Bezeichner, die mit einem Unterstrich beginnen, gefolgt von einem Großbuchstaben
    • Bezeichner mit benachbarten Unterstrichen (oder "Doppelstriche")
  • Reserviert im globalen Namespace:
    • Bezeichner beginnen mit einem Unterstrich
  • Außerdem ist alles im std Namespace reserviert. (Sie können jedoch Vorlagenspezialisierungen hinzufügen.)

Aus dem C ++ - Standard 2003:

17.4.3.1.2 Globale Namen [lib.global.names]

Bestimmte Gruppen von Namen und Funktionssignaturen sind immer für die Implementierung reserviert:

  • Jeder Name, der einen doppelten Unterstrich ( __ ) enthält oder mit einem Unterstrich beginnt, gefolgt von einem Großbuchstaben (2.11), ist für jede Verwendung reserviert.
  • Jeder Name, der mit einem Unterstrich beginnt, ist für die Implementierung als Name im globalen Namespace reserviert. 165

165) Solche Namen sind auch in namespace ::std (17.4.3.1) reserviert.

Da C ++ auf dem C-Standard (1.1 / 2, C ++ 03) basiert und C99 eine normative Referenz (1.2 / 1, C ++ 03) ist, gelten diese auch aus dem C-Standard 1999:

7.1.3 Reservierte Identifikatoren

Jede Kopfzeile deklariert oder definiert alle in der zugehörigen Unterklausel aufgelisteten Bezeichner und deklariert oder definiert optional Bezeichner, die in den zugehörigen Bibliotheksanweisungen Unterklauseln und Bezeichnern aufgeführt sind, die immer für die Verwendung oder als Dateibereichsbezeichner reserviert sind.

  • Alle Bezeichner, die mit einem Unterstrich und einem Großbuchstaben oder einem anderen Unterstrich beginnen, sind immer für die Verwendung reserviert.
  • Alle Bezeichner, die mit einem Unterstrich beginnen, sind immer für die Verwendung als Bezeichner mit dem Dateibereich sowohl im normalen als auch im Namensraum reserviert.
  • Jeder Makroname in einem der folgenden Unterklauseln (einschließlich der zukünftigen Bibliotheksanweisungen) ist für die Verwendung wie angegeben reserviert, wenn einer der zugehörigen Header enthalten ist; sofern nicht ausdrücklich anders angegeben (siehe 7.1.4).
  • Alle Bezeichner mit externer Verknüpfung in einem der folgenden Unterabschnitte (einschließlich der zukünftigen Bibliotheksanweisungen) sind immer für die Verwendung als Bezeichner mit externer Verknüpfung reserviert. 154
  • Jeder Bezeichner mit dem Dateibereich, der in einem der folgenden Unterabschnitte aufgeführt ist (einschließlich der zukünftigen Bibliotheksanweisungen), ist für die Verwendung als Makroname und als Bezeichner mit Dateibereich im selben Namensbereich reserviert, wenn einer der zugehörigen Header enthalten ist.

Keine anderen Kennungen sind reserviert. Wenn das Programm einen Bezeichner in einem Kontext deklariert oder definiert, in dem es reserviert ist (anders als gemäß 7.1.4 zulässig) oder einen reservierten Bezeichner als Makronamen definiert, ist das Verhalten nicht definiert.

Wenn das Programm (mit #undef ) eine Makrodefinition eines Bezeichners in der ersten oben aufgelisteten Gruppe entfernt, ist das Verhalten undefiniert.

154) Die Liste der reservierten Bezeichner mit externer Verknüpfung enthält errno , math_errhandling , setjmp und va_end .

Andere Einschränkungen könnten zutreffen. Zum Beispiel reserviert der POSIX-Standard viele Kennungen, die wahrscheinlich in normalem Code angezeigt werden:

  • Namen, die mit einem Großbuchstaben E folgen einer Ziffer oder einem Großbuchstaben:
    • Kann für zusätzliche Fehlercodenamen verwendet werden.
  • Namen, die mit entweder beginnen, is oder to gefolgt von einem Kleinbuchstaben
    • kann für zusätzliche Charaktertest- und Konvertierungsfunktionen verwendet werden.
  • Namen, die mit LC_ beginnen, gefolgt von einem Großbuchstaben
    • kann für zusätzliche Makros verwendet werden, die Gebietsschemaattribute angeben.
  • Die Namen aller vorhandenen mathematischen Funktionen mit dem Zusatz f oder l sind reserviert
    • für entsprechende Funktionen, die mit Float- bzw. Long-Double-Argumenten arbeiten.
  • Namen, die mit SIG gefolgt von einem Großbuchstaben beginnen, sind reserviert
    • für zusätzliche Signalnamen.
  • Namen, die mit SIG_ gefolgt von einem Großbuchstaben beginnen, sind reserviert
    • für zusätzliche Signalaktionen.
  • Namen, die mit str , mem oder wcs gefolgt von einem Kleinbuchstaben beginnen, sind reserviert
    • für zusätzliche String- und Array-Funktionen.
  • Namen, die mit PRI oder SCN gefolgt von einem Kleinbuchstaben oder X sind reserviert
    • für zusätzliche Formatbezeichnermakros
  • Namen, die mit _t sind reserviert
    • für zusätzliche Typnamen.

Obwohl die Verwendung dieser Namen für Ihre eigenen Zwecke momentan kein Problem darstellt, erhöhen sie doch die Möglichkeit eines Konflikts mit zukünftigen Versionen dieses Standards.

Persönlich starte ich Kennungen nicht nur mit Unterstrichen. Neue Ergänzung zu meiner Regel: Verwenden Sie keine doppelten Unterstriche, das ist einfach, da ich selten Unterstriche verwende.

Nach der Recherche zu diesem Artikel _t ich meine Bezeichner nicht mehr mit _t da dies vom POSIX-Standard reserviert ist.

Die Regel über jeden Bezeichner, der mit _t endet, _t mich sehr überrascht. Ich denke, das ist ein POSIX-Standard (noch nicht sicher) auf der Suche nach Klärung und offizielles Kapitel und Vers. Dies ist aus dem GNU-Libtool-Handbuch , das reservierte Namen auflistet.

CesarB stellte den folgenden opengroup.org/onlinepubs/009695399/functions/xsh_chap02_02.html reservierten Symbolen den folgenden Link zur Verfügung und stellt fest, dass viele andere reservierte Präfixe und Suffixe ... dort gefunden werden können. Die reservierten POSIX 2008- Symbole sind hier definiert. Die Einschränkungen sind etwas nuancierter als die oben genannten.

In C ++ ist es üblich, Membervariablen mit einer Art Präfix zu benennen, um die Tatsache zu kennzeichnen, dass es sich um Membervariablen und nicht um lokale Variablen oder Parameter handelt. Wenn Sie von einem MFC-Hintergrund stammen, verwenden Sie wahrscheinlich m_foo . Ich habe myFoo gelegentlich gesehen.

C # (oder möglicherweise nur .NET) scheint zu empfehlen, nur einen Unterstrich zu verwenden, wie in _foo . Ist dies nach dem C ++ - Standard erlaubt?


Die Regeln zur Vermeidung der Kollision von Namen sind beide im C ++ - Standard (siehe Stroustrup-Buch) und von C ++ - Gurus (Sutter, etc.) erwähnt.

Persönliche Regel

Weil ich mich nicht mit Fällen befassen wollte und eine einfache Regel wollte, habe ich eine persönliche entworfen, die sowohl einfach als auch korrekt ist:

Wenn Sie ein Symbol benennen, vermeiden Sie eine Kollision mit Compiler / OS / Standard-Bibliotheken, wenn Sie

  • Beginnen Sie niemals ein Symbol mit einem Unterstrich
  • Nennen Sie niemals ein Symbol mit zwei aufeinander folgenden Unterstrichen.

Natürlich hilft es auch, wenn Sie Ihren Code in einen eindeutigen Namespace setzen, um Kollisionen zu vermeiden (schützt aber nicht vor bösen Makros)

Einige Beispiele

(Ich benutze Makros, weil sie C-C ++ - Symbole mehr Code-verschmutzen, aber es könnte alles von Variablenname zu Klassenname sein)

#define _WRONG
#define __WRONG_AGAIN
#define RIGHT_
#define WRONG__WRONG
#define RIGHT_RIGHT
#define RIGHT_x_RIGHT

Extrakte aus C ++ 0x Entwurf

Aus der Datei n3242.pdf (ich erwarte, dass der endgültige Standardtext ähnlich ist):

17.6.3.3.2 Globale Namen [global.names]

Bestimmte Gruppen von Namen und Funktionssignaturen sind immer für die Implementierung reserviert:

- Jeder Name, der einen doppelten Unterstrich _ _ enthält oder mit einem Unterstrich gefolgt von einem Großbuchstaben (2.12) beginnt, ist der Implementierung für jede Verwendung vorbehalten.

- Jeder Name, der mit einem Unterstrich beginnt, ist für die Implementierung reserviert, um als Name im globalen Namespace verwendet zu werden.

Aber auch:

17.6.3.3.5 Benutzerdefinierte Literalsuffixe [usrlit.suffix]

Literale Suffix-IDs, die nicht mit einem Unterstrich beginnen, sind für die zukünftige Standardisierung reserviert.

Diese letzte Klausel ist verwirrend, es sei denn, Sie denken, dass ein Name, der mit einem Unterstrich und einem Kleinbuchstaben beginnt, OK wäre, wenn er nicht im globalen Namespace definiert wäre ...


Von MSDN :

Die Verwendung von zwei sequenziellen Unterstreichungszeichen (__) am Anfang eines Bezeichners oder eines einzelnen führenden Unterstrichs, gefolgt von einem Großbuchstaben, ist für C ++ - Implementierungen in allen Bereichen reserviert. Sie sollten vermeiden, einen führenden Unterstrich gefolgt von einem Kleinbuchstaben für Namen mit Dateibereich wegen möglicher Konflikte mit aktuellen oder zukünftigen reservierten Bezeichnern zu verwenden.

Dies bedeutet, dass Sie einen einzelnen Unterstrich als Präfix für Mitgliedsvariablen verwenden können, sofern ein Kleinbuchstabe folgt.

Dies ist offensichtlich Abschnitt 17.4.3.1.2 des C ++ - Standards entnommen, aber ich kann keine Originalquelle für den vollständigen Standard online finden.

Siehe auch diese Frage .


Wie für den anderen Teil der Frage, ist es üblich, den Unterstrich am Ende des Variablennamens zu setzen, um nicht mit irgendetwas internem zu kollidieren.

Ich mache das sogar innerhalb von Klassen und Namespaces, weil ich mich dann nur an eine Regel erinnern muss (im Vergleich zu "am Ende des Namens im globalen Bereich und am Anfang des Namens überall sonst").





c++-faq