R"(x)" literals are neat not just because whitespaces matter, but also because they are tokenized before macro expansion. Thus you can write a C23 detector like this:
#include<stdio.h>
#define r(R) R"()"
int main()
{
puts(r()[0] ? "C99" /* r() evaluates to "()" */
: "C23" /* r() evaluates to "" */);
}
Output: https://gcc.godbolt.org/z/Wj3s6KEGKI have used that trick here:
https://www.ioccc.org/years.html#2015_yang
(C23 wasn't a thing back then, but the same trick can be used to differentiate C++11 from C++98).