Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Error subtracting hex constant when it ends in an 'E'

int main()
{
    0xD-0; // Fine
    0xE-0; // Fails
}

This second line fails to compile on both clang and gcc. Any other hex constant ending is ok (0-9, A-D, F).

Error:

<source>:4:5: error: unable to find numeric literal operator 'operator""-0'
    4 |     0xE-0;
      |     ^~~~~

I have a fix (adding a space after the constant and before the subtraction, so I’d mainly like to know why? Is this something to do with it thinking there’s an exponent here?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

https://godbolt.org/z/MhGT33PYP

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading