Frage g ++ 4.7 wertet den Operator "" als Geschwister zur Makroexpansion aus


Ich habe etwas Code nach GCC 4.7 (ab 4.6) verschoben und bin auf einige Compilerfehler gestoßen GCC 4.7 Portierungshilfe:

Benutzerdefinierte Literale und Leerzeichen

Der C ++ - Compiler im ISO C11-Modus std={c++11,c++0x,gnu++11,gnu++0x}   unterstützt benutzerdefinierte Literale, die mit einigen gültigen nicht kompatibel sind   ISO C ++ 03-Code.

Insbesondere werden nun Leerzeichen nach einem String-Literal benötigt   vor etwas, das ein gültiges benutzerdefiniertes Literal sein könnte. Nehmen Sie die   gültiger ISO C ++ 03 Code

const char *p = "foobar"__TIME__;

In C ++ 03, der ZEIT Makro expandiert zu einem String-Literal und ist   mit dem anderen verkettet. In C ++ 11 __TIME__ wird nicht erweitert,   stattdessen operator "" __TIME__ wird nachgeschlagen, was zur Folge hat   folgende Diagnose:

error: unable to find string literal operator  ‘operator"" __TIME__’

Dies gilt für jedes String-Literal, dem von einigen ohne Leerzeichen gefolgt wird   Makro. Um das Problem zu beheben, fügen Sie einfach ein Leerzeichen zwischen dem Zeichenfolgeliteral und   der Makroname.

Während ich die Fehler beheben konnte, möchte ich es wissen Warum Ich muss das tun. __TIME__ ist ein Makro, also "something"__TIME__ würde sich ändern "something""15:52:03" (oder ähnlich) in der Vorverarbeitungsstufe, so dass der Compiler niemals die Möglichkeit haben würde, es als zu sehen operator "".

Ist dieses Verhalten von Standards genehmigt oder handelt es sich um einen Fehler?


13
2017-08-10 21:58


Ursprung


Antworten:


Das Problem ist das "foobar"__TIME__ wird nicht mehr in die Präprozessor-Tokens in Token umgewandelt "foobar" gefolgt von __TIME__.

Präprozessor-Token "haben die lexikalische Form eines Schlüsselworts, eines Bezeichners, eines Literals, eines Operators oder eines Interpunktionszeichens." Das Hinzufügen von benutzerdefinierten Literalen ändert, was als Präprozessor-Token gelehrt wird. Jetzt "foobar"__TIME__ ist eine Single benutzerdefiniertes Zeichen-Literal Präprozessor-Token und so, wenn Phase 4 der Übersetzung auftritt, die ersetzen würde __TIME__ mit dem "15:52:03", es gibt kein __TIME__ Token, um auf diese Weise ersetzt zu werden.

Ja, dieses Verhalten ist im Standard angegeben.

Aufgrund der cinttypes-Makros sieht es so aus, als ob mehr Code davon betroffen ist, als das Komitee realisiert hat und sie erwägen, es anzusprechen. Einige Compiler sind bereits damit beschäftigt, Probleme mit cinttypes zu behandeln, jedoch nicht in einer Weise, die diese Verwendung von beheben würde __TIME__ für dich. Ich denke deine beste Wette ist, nur den Code zu ändern.


16
2017-08-10 22:09