Почему "0xe + 1" не компилируется?

Посмотрите на этот фрагмент кода:

int a = 0xe+1;

Clang, gcc, icc не компилируют это:

t.cpp:1:12: error: invalid suffix '+' on integer constant

MSVC успешно компилируется.

Какой компилятор прав? Если clang и gcc верны, почему это происходит?

Примечание: если я добавлю пробел до +, код компилируется. Если я изменяю 0xe на 0xf, он тоже компилируется. Может быть, это должно что-то делать с экспоненциальной нотацией (например, 1.2e+3)?

Ответ 1

0xe+1 рассматривается как один токен предварительной обработки номера предварительной обработки. Это правило токенизации не совсем совпадает с определением числовых литералов в обычной грамматике; номера предварительной обработки определяются как

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 .

Если правила токенизации были основаны на определениях числового литерала вместо более простого определения числа "предварительной обработки", ваше выражение будет обозначаться как 0xe + 1, но поскольку правила не совпадают, вы получаете один 0xe+1, который не является допустимым литералом.