c++language-lawyerc-preprocessoruser-defined-literals

Do preprocessor defines substitute in `operator""_name`


Consider the following example provided by Aykhan Hagverdili:

#include <string>

using std::operator""s;

#define s foobar

auto s = "hello world"s;

Some compilers would substitute s and fail compilation. Some compilers would not substitute s.

See the result here: https://godbolt.org/z/jx4nhYczd gcc fails, clang compiles

Which is right?


Solution

  • "hello world"s is, since C++11, a single preprocessing token matching the user-defined-string-literal grammar production.

    Macros substitute on the level of preprocessing tokens. Since there is no s preprocessing token, there can't be any substitution of your macro.

    As a result your code is well-formed in C++14 or later. std::operator""s is chosen. In C++11 there was no std::operator""s.

    However, before C++11 when user-defined literals were introduced, "hello world"s would have been two preprocessing tokens "hello" and s, so the latter one would have been substituted with your macro.

    This is even explicitly mentioned in [diff.cpp03.lex]/2 as a backwards-incompatible change with C++11.