Читая стандарт С++ 17, мне кажется, что существует несоответствие между pp-number обрабатывается препроцессором, и числовыми литералами, например, user-defined-integer-literal, так как они определены для обработки " верхний "язык.
Например, следующее правильно обрабатывается как число pp-number согласно грамматике препроцессора:
123_e+1
Но помещенный в контекст фрагмента кода, совместимого с С++ 11,
int operator"" _e(unsigned long long)
{ return 0; }
int test()
{
return 123_e+1;
}
текущие компиляторы Clang или GCC (я не проверял другие) вернет ошибку, подобную этой:
unable to find numeric literal operator 'operator""_e+1'
где operator"" _e(...) не найден и попытка определить operator"" _e+1(...) будет недопустимой.
Похоже, это происходит потому, что компилятор сначала использует лексему токен как pp-number, но затем не может выполнить откат и применить грамматические правила для определяемого user-defined-integer-literal при синтаксическом анализе конечного выражения.
Для сравнения: следующий код компилируется нормально:
int operator"" _d(unsigned long long)
{ return 0; }
int test()
{
return 0x123_d+1; // doesn't lex as a 'pp-number' because 'sign' can only follow [eEpP]
}
Это правильное прочтение стандарта? И если да, то разумно ли, чтобы компилятор обрабатывал этот, возможно, редкий, угловой случай?