Integer Literal Types in C

Bare Literals

Take a look at these variable declarations:

```int a = 123;
unsigned int b = 123;
uint64_t c = 123;
```

We're using the same integer literal, `123`, to initialize three different integer types.

In practice, all three initializations work as you'd expect — `a`, `b`, and `c` all end up initialized to the positive integer value one-hundred-and-twenty-three.

But what is the type of the literal `123` taken on its own?

If a literal is a decimal constant (e.g. `123`), its type is the first entry in the following list that can represent its value:

1. `int`
2. `long int`
3. `long long int`

If a literal is an octal or hexadecimal constant (e.g. `0123` or `0x123`), its type is the first entry in the following list that can represent its value:

1. `int`
2. `unsigned int`
3. `long int`
4. `unsigned long int`
5. `long long int`
6. `unsigned long long int`

Source: C11 Standard (N1570) 6.4.4.1.

Negative Literals

There are no negative literals.

`-123` isn't an integer literal — it's an expression consisting of the positive integer literal `123` and the unary negation operator `-`.

Literal Suffixes

You can add letter suffixes to specify a literal's type.

`u` or `U` makes the type `unsigned`:

• `123u``unsigned int`

`l` or `L` makes the type `long`:

• `123l``long int`

`ll` or `LL` makes the type `long long`:

• `123ll``long long int`

Combinations work as expected:

• `123ul``unsigned long int`
• `123ull``unsigned long long int`

Fixed-Width Macros

The `stdint.h` header contains a set of function macros for adding the appropriate suffixes for fixed-width integer types.

Signed:

• `INT8_C()`
• `INT16_C()`
• `INT32_C()`
• `INT64_C()`

Unsigned:

• `UINT8_C()`
• `UINT16_C()`
• `UINT32_C()`
• `UINT64_C()`

For example `UINT64_C(123)` will expand to `123ULL` or `123UL`, whichever is appropriate for the system.