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


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, werden Sie wahrscheinlich verwenden m_foo. Ich habe es auch gesehen myFoo gelegentlich.

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


800
2017-10-23 07:02


Ursprung


Antworten:


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
  • Auch alles in der std Namensraum ist 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 beginnt mit einem Unterstrich gefolgt von einem Großbuchstaben (2.11) ist der Implementierung für jede Verwendung vorbehalten.
  • Jeder Name, der mit einem Unterstrich beginnt, ist für die Implementierung als Name im globalen Namespace reserviert.165

165) Solche Namen sind auch im Namensraum reserviert ::std (17.4.3.1).

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 Bezeichner, die in der zugehörigen Unterklausel aufgeführt sind, und   optional deklariert oder definiert Bezeichner, die in den zugehörigen zukünftigen Bibliotheksanweisungen aufgelistet sind, Subklauseln und Bezeichner, die immer entweder für jede Verwendung oder zur Verwendung als Dateibereichsbezeichner reserviert sind.

  • Alle Bezeichner, die mit einem Unterstrich und einem Großbuchstaben oder einem anderen beginnen   Unterstriche sind immer für jede Verwendung reserviert.
  • Alle Bezeichner, die mit einem Unterstrich beginnen, sind immer für die Verwendung als Bezeichner reserviert   mit dem Dateibereich in den normalen und Tag-Namensräumen.
  • Jeder Makroname in einem der folgenden Unterklauseln (einschließlich der zukünftigen Bibliothek)   Richtungen) 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 Kennungen mit externer Verknüpfung in einem der folgenden Unterabschnitte (einschließlich der   zukünftige Bibliotheksanweisungen) sind immer für die Verwendung als Kennungen mit externen reserviert   Verknüpfung.154
  • Jeder Bezeichner mit Dateiumfang, der in einem der folgenden Abschnitte aufgeführt ist (einschließlich der   zukünftige Bibliotheksanweisungen) ist für die Verwendung als Makroname und als Bezeichner mit   Dateibereich im selben Namensraum, wenn einer der zugehörigen Header enthalten ist.

Keine anderen Kennungen sind reserviert. Wenn das Programm einen Bezeichner in a deklariert oder definiert   Kontext, in dem es reserviert ist (anders als in 7.1.4 erlaubt) oder definiert ein reserviertes   Bezeichner als Makroname, das Verhalten ist nicht definiert.

Wenn das Programm entfernt (mit #undef) jede Makrodefinition eines Bezeichners in der ersten   Gruppe ist das Verhalten nicht definiert.

154) Die Liste der reservierten Kennungen 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 Kapital beginnen E gefolgt von einer Ziffer oder einem Großbuchstaben:
    • Kann für zusätzliche Fehlercodenamen verwendet werden.
  • Namen, die mit beiden beginnen is oder to gefolgt von einem Kleinbuchstaben
    • kann für zusätzliche Charaktertest- und Konvertierungsfunktionen verwendet werden.
  • Namen, die mit beginnen LC_ gefolgt von einem Großbuchstaben
    • kann für zusätzliche Makros verwendet werden, die Gebietsschemaattribute angeben.
  • Namen aller vorhandenen mathematischen Funktionen mit Suffix f oder l sind reserviert
    • für entsprechende Funktionen, die mit Float- bzw. Long-Double-Argumenten arbeiten.
  • Namen, die mit beginnen SIG gefolgt von einem Großbuchstaben sind vorbehalten
    • für zusätzliche Signalnamen.
  • Namen, die mit beginnen SIG_ gefolgt von einem Großbuchstaben sind vorbehalten
    • für zusätzliche Signalaktionen.
  • Namen beginnend mit str, mem, oder wcs gefolgt von einem Kleinbuchstaben sind vorbehalten
    • für zusätzliche String- und Array-Funktionen.
  • Namen beginnend mit PRI oder SCN gefolgt von einem Kleinbuchstaben oder X sind reserviert
    • für zusätzliche Formatbezeichnermakros
  • Namen, die mit enden _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 beende ich meine Kennungen nicht mehr mit _t wie dies vom POSIX-Standard reserviert ist.

Die Regel für jeden Bezeichner, der mit endet _t hat 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 von der GNU libtool Handbuch, Liste reservierte Namen.

CesarB stellte den folgenden Link zur Verfügung POSIX 2004 reservierte Symbole und Notizen, dass viele andere reservierte Präfixe und Suffixe ... dort gefunden werden können. Das POSIX 2008 Reservierte Symbole sind hier definiert. Die Einschränkungen sind etwas nuancierter als die oben genannten.


739
2017-10-23 07:27



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 ein persönlich eine, 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.

170
2017-10-23 07:06



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 auf ihn 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.


28
2017-11-14 20:03



Was den anderen Teil der Frage anbelangt, ist es üblich, den Unterstrich bei der Ende des Variablennamens, 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").


21
2017-10-23 07:05



Ja, Unterstriche können überall in einem Bezeichner verwendet werden. Ich glaube, die Regeln sind: entweder a-z, A-Z, _ im ersten Zeichen und die + 0-9 für die folgenden Zeichen.

Underscore-Präfixe sind im C-Code üblich - ein einzelner Unterstrich bedeutet "privat", und doppelte Unterstriche sind normalerweise für die Verwendung durch den Compiler reserviert.


2