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?
"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.