21.2.1 Integer Literals

Integers literals can be expressed in several numeration bases.

Decimal numbers use the usual syntax [1-9][0-9]*. For example, 2345.

Octal numbers are expressed using a prefix 0o (or 0O) followed by one or more digits in the range [0-7]. Examples are 0o0, 0o100 and 0o777.

Hexadecimal numbers are expressed using a prefix 0x (or 0X) followed by one or more hexadecimal digits in the range [0-f]. Examples are 0x0 and 0xfe00ffff. Note that both the x in the prefix and the letters in the hexadecimal number are case insensitive. Thus, 0XdeadBEEF is a valid (but ugly as hell) literal.

Binary numbers are expressed using a prefix 0b (or 0B) followed by one or more binary digits in the range [0-1]. Examples of binary literals are 0b0 and 0B010.

Negative numbers, of any numeration base, are constructed using the minus operator as explained below. Therefore the minus symbol - in negative numbers is not part of the literal themselves.

21.2.1.1 The digits separator _

The character _ can appear anywhere in a numeric literal except as the first character. It is ignored, and its purpose is to make it easier for programmers to read them:

0xf000_0000_0000_0000
0b0000_0001_0000_0001

21.2.1.2 Types of integer literals

The type of a numeric literal is the smallest signed integer capable of holding it, starting with 32 bits, in steps of powers of two and up to 64 bits.11

So, for example, the value 2 has type int<32>, but the value 0xffff_ffff has type int<64>, because it is out of the range of signed 32-bit numbers.

A set of suffixes can be used to construct integer literals of certain types explicitly. L or l is for 64-bit integers. H or h is for 16-bit integers (also known as halves), B or b is for 8-bit integers (also known as bytes) n or N is for 4-bit integers (also known as nibbles) and t or T is for 1-bit integers (also known as bits).

Thus, 10L is a 64-bit integer with value 0x0000_0000_0000_000A, 10H is a 16-bit integer with value 0x000A and 10b is a 8-bit integer with value 0x0A.

Similarly, the signed or unsigned attribute of an integer can be explicitly specified using the suffix u or U (the default are signed types). For example 0xffff_ffffU has type uint<32> and 0ub has type uint<8>. It is possible to combine width-indicating suffixes with signedness suffixes: 10UL denotes the same literal as 10LU. Note that bit constants (suffix t or T) are always unsigned and do not require U.

The above rules guarantee that it is always possible to determine the width and signedness of an integer constant just by looking at it, with no ambiguity.


Footnotes

(11)

Rationale: the width of a C “int” is 32 bits in most currently used architectures, and binary data formats are usually modelled after C.