2014-10-10 22 views
17

Are dollar-signs allowed in identifiers in C++03? bedeutet, dass Dollarzeichen in Bezeichnern in C++ 03 nicht zulässig sind. GCC stellt es als C extension zur Verfügung und gibt ordnungsgemäß eine Diagnose im C++ 03-Modus. In C++ 11 wird jedoch int $ = 0 ohne Warnung kompiliert.Erlaubt C++ 11 Dollarzeichen in Bezeichnern?

Diese answer Gründe dafür, dass $ weil keine Diagnose erlaubt sein kann Implementierung definiert Bezeichner erforderlich ist: auch

The answer here is "Maybe": According to §2.11, identifiers may consist of digits and identifier-nondigits, starting with one of the latter. identifier-nondigits are the usual a-z , A-Z and underscore, in addition since C++11 they include universal-character-names (e.g. \uBEAF , \UC0FFEE32), and other implementation-defined characters. So it is implementation defined if using $ in an identifier is allowed. VC10 and up supports that, maybe earlier versions, too. It even supports identifiers like こんばんわ .

But: I wouldn't use them. Make identifiers as readable and portable as possible. $ is implementation defined and thus not portable.

Diese Sprache ist in der C++ 03-Standard, so dass ich das nicht finden ein sehr überzeugendes Argument sein.

§2.10/2

In addition, some identifiers are reserved for use by C++ implementations and standard libraries (17.6.4.3.2) and shall not be used otherwise; no diagnostic is required.

, was in der Standardänderung ermöglicht $ als Identifikator Name verwendet werden?

+2

Clang warnt vor diesem. –

+0

@Shafik Verwirrend genug, das [Antwort] (http://stackoverflow.com/a/14595459/3920237) Links zu alten GCC-Dokumentation, die explizit besagt, dass C++ in Bezeichnern $ verboten. Sie haben es nach [preprocessor options] verschoben (https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html # Preprocessor-Optionen) mit der einzigen Beschreibung 'Accept '$' in Bezeichnern.' –

+0

In der Vergangenheit verwendete DEC $ in allen Systemdienst- und Bibliotheksfunktionsnamen mit $$ in allen internen Funktionen. Alle DEC-Compiler sind entweder Erweiterungen, die $ -Symbolnamen oder Pragmas für das Mapping erlauben (wie bei ADA). – user3344003

Antwort

17

Dies ist ein implementierungsdefiniertes Verhalten, $ ist nicht in der Grammatik für Bezeichner enthalten. Die Regeln für die Bezeichnernamen in C++ 11 sind:

  1. Es ist nicht mit einer Reihe
  2. beginnen kann aus Buchstaben bestehen, Zahlen unterstreichen, universelle Zeichennamen und Implementierung definiert Zeichen
  3. kann kein keyword

Implementierung definiert Zeichen erlaubt sind und viele Compiler s-Unterstützung als eine Erweiterung, einschließlich gcc, clang, Visual Studio und wie in einer comment offenbar DEC C++ compilers notiert.

Die Grammatik abgedeckt ist im draft C++ standard Abschnitt 2.11Indentifier, habe ich zusätzliche Hinweise beginnend mit <-:

identifier: 
    identifier-nondigit   <- Can only start with a non-digit 
    identifier identifier-nondigit <- Next two rules allows for subsequent 
    identifier digit    <- characters to be those outlined in 2 above 
identifier-nondigit: 
    nondigit      <- a-z, A-Z and _ 
    universal-character-name 
    other implementation-defined characters 
[...] 

Wenn wir diesen Code kompilieren mit clang mit der -pedantic-errors Flagge wird es nicht kompilieren:

int $ = 0 

und generiert den folgenden Fehler:

error: '$' in identifier [-Werror,-Wdollar-in-identifier-extension] 
int $ = 0; 
    ^
3

Ich glaube nicht. Das Dollarzeichen ist in ASCII 0x24, das nicht in einem der Bereiche liegt, die in Anhang E.1 (charname.allowed) des Standards definiert sind. Und da es weder Ziffer noch Nicht-Ziffer ist, muss es ein implementierungsdefiniertes Zeichen sein. Ich stimme also zu, dass dies nicht portable C++ 11 ist. Beachten Sie auch, dass ein Bezeichner nicht mit einem Universalzeichen beginnen darf, während ein Bezeichner mit einem Zeichen beginnen darf, das von der Implementierung zugelassen wird.

+1

"Nicht tragbar" und "nicht erlaubt" (schlecht geformt) sind beide schlechte Dinge, aber nicht das Gleiche. Das ist also keine direkte Antwort auf die Frage. – MSalters

+1

Ich bin mir dessen bewusst. Ich habe hier "nicht portierbar" als Synonym für "implementierungsdefiniertes Verhalten" verwendet. – dom0