Actually, this behaviour is mandated by the C++ standard (and documented), as strange as it may seem. This is because of how C++ compiles using Preprocessing Tokens (a.k.a pp-tokens).
If we look closely at how the compiler generates a token for numbers:
A preprocessing number is made up of a digit, optionally preceded by a period, and may be followed by letters, underscores, digits, periods, and any one of: e+ e- E+ E-.
According to this, The compiler reads 0x
, then E-
, which it interprets it as part of the number as having E-
is allowed in a numeral pp-token and no space precedes it or is in between the E
and the -
(this is why adding a space is an easy fix).
This means that 0xE-0
is taken in as a single preprocessing token. In other words, the compiler interprets it as one number, instead of two numbers 0xE
and 0
and an operation -
. Therefore, the compiler is expecting E
to represent an exponent for a floating-point literal.
Now let's take a look at how C++ interprets floating-point literals. Look at the section under "Examples". It gives this curious code sample:
<< "\n0x1p5 " << 0x1p5 // double
<< "\n0x1e5 " << 0x1e5 // integer literal, not floating-point
E
is interpreted as part of the integer literal, and does not make the number a hexadecimal floating literal! Therefore, the compiler recognizes 0xE
as a single, integer, hexidecimal number. Then, there is the -0
which is technically part of the same preprocessing token and therefore is not an operator and another integer. Uh oh. This is now invalid, as there is no -0
suffix.
And so the compiler reports an error, as such.