2012-11-30 2 views
9

Kann ein mehrzeiliges rohe Zeichenkettenliteral ein Argument eines Präprozessormakros sein?Mehrzeilige unverarbeitete Zeichenkettenliterale als Präprozessormakroargumente

#define IDENTITY(x) x 

int main() 
{ 
    IDENTITY(R"(
    )"); 
} 

Dieser Code wird nicht in g ++ 4.7.2 und VC++ 11 (Nov.CTP) kompiliert.
Ist es ein Compiler (Lexer) Bug?

+1

Es scheint zu sein, entweder ein Lexer oder ein Pre-Prozessor-Problem, zumindest in GCC. Wenn ich eine Vorprozessor-Zeilenfortsetzung (die die Zeile in einem umgekehrten Schrägstrich endet) hinzufüge, kompiliert sie, aber die Zeichenfolge enthält das Zeilenfortsetzungszeichen. Getestet mit GCC 4.7.2. –

+1

Ich habe einen Fehler zum Verfolgen des Problems in Visual C++ CTP geöffnet. –

+1

Für was es wert ist, Clang 3.1 hat kein Problem, Ihr Beispiel zu kompilieren. – bfroehle

Antwort

2

Mehrere makro Anrufungen sind legal - , da Sie eine rohe Stringliteral verwenden, sollten sie

zusammengestellt

Es ist eine bekannte GCC Bug dafür:

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52852

Wenn Sie gewesen Mit regulären (nicht gezeichneten) Strings wäre es illegal gewesen.

printf(R"HELLO 
    WORLD\n"); 

Aber nicht dies:

Dies sollte zusammengestellt

printf("HELLO 
    WORLD\n"); 

als

printf("HELLO\nWORLD\n"); 

codiert werden, wenn eine neue Linie zwischen HALLO und WORLD oder soll Dies sollte als

printf("HELLO " 
    "WORLD\n"); 

Wenn keine dazwischenliegende neue Zeile gemeint war.

Möchten Sie eine neue Zeile in Ihrem Literal? Wenn dies der Fall könnten dann nicht Sie

IDENTITY("(\n)"); 

Die C-Compiler-Dokumentation unter

http://gcc.gnu.org/onlinedocs/cpp.pdf 

Staaten verwenden, die in Abschnitt 3.3 (Makro) Argumente, dass

"The invocation of the macro need not be 
restricted to a single logical line—it can cross 
as many lines in the source file as you wish." 
+3

Ihr erstes Beispiel kompiliert nicht, weil es ein gewöhnliches Zeichenfolgenliteral ist. Das OP hat ein rohe String-Literal verwendet, das Quellzeilen-Zeilenumbrüche enthalten kann (siehe [lex.string], insbesondere Par. 4 und 5). Ich Seite mit dem OP, dass es ein Compiler-Bug ist. – Angew