Ответ 1
Вы стали жертвой правила максимального жаворонка, при котором лексический анализатор принимает как можно больше символов, чтобы сформировать действительный токен.
Это описано в разделе [lex.pptoken] p3, где говорится (выделено мое):
В противном случае следующий токен предварительной обработки - это самая длинная последовательность символов, которая может составлять токен предварительной обработки, даже если это приведет к сбою в дальнейшем лексическом анализе, за исключением того, что имя заголовка ([lex.header]) формируется только внутри #include директивы.
и включает в себя несколько примеров:
[ Пример:
#define R "x" const char* s = R"y"; // ill-formed raw string, not "x" "y"
- конец примера]
4 [Пример: фрагмент программы 0xe + foo анализируется как токен числа предварительной обработки (тот, который не является допустимым плавающим или целочисленным литеральным токеном), даже если синтаксический анализ трех токенов предварительной обработки 0xe, + и foo может привести к действительному выражению (например, если бы foo был макросом, определенным как 1). Аналогично, фрагмент программы 1E1 анализируется как номер предварительной обработки (тот, который является допустимым плавающим литеральным токеном), независимо от того, является ли E именем макроса. - конец примера]
5 [Пример: фрагмент программы x +++++ y анализируется как x ++ ++ + y, что, если x и y имеют целочисленные типы, нарушает ограничение на операторы приращения, даже если синтаксический анализ x ++ + ++ y может дать правильное выражение. - конец примера]
Это правило действует в нескольких других хорошо известных случаях, таких как a +++++ b и токены> =, для которых требуется исправление.
Для справки грамматика pp-токена выглядит следующим образом:
pp-number: digit . digit pp-number digit pp-number identifier-nondigit pp-number ' digit pp-number ' nondigit pp-number e sign pp-number E sign pp-number p sign pp-number P sign pp-number .
Обратите внимание на производство e sign
, которое и привлекает этот случай. Если, с другой стороны, вы используете d
как ваш второй пример, вы не попали бы в это (смотрите его вживую).
Кроме того, добавление пробелов также решило бы вашу проблему, так как вы больше не подвергались бы максимальному жаворонку (см. Это в прямом эфире на кресте):
123_e + 1