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?

The answer is, it depends.

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:

l or L makes the type long:

ll or LL makes the type long long:

Combinations work as expected:

Fixed-Width Macros

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

Signed:

Unsigned:

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