Search code examples
c++c++11c-preprocessorrawstring

In C++11 what should happen first: raw string expansion or macros?


This code works in Visual C++ 2013 but not in gcc/clang:

#if 0
R"foo(
#else
int dostuff () { return 23; }
// )foo";
#endif
dostuff();

Visual C++ removes the if 0 first. Clang expands the R raw string first (and never defining dostuff). Who is right and why?


Solution

  • [Update: Adrian McCarthy comments below saying MSVC++ 2017 fixes this]

    GCC and clang are right, VC++ is wrong.

    2.2 Phases of translation [lex.phases]:

    [...]

    1. The source file is decomposed into preprocessing tokens (2.5) and sequences of white-space characters (including comments).

    2. Preprocessing directives are executed, [...]

    And 2.5 Preprocessing tokens [lex.pptoken] lists string-literals amongst the tokens.

    Consequently, parsing is required to tokenise the string literal first, "consuming" the #else and dostuff function definition.