# What is the exact value range for unsigned long?

• A+
Category：Languages

I am working through the exercises in the book "Learn C the hard way". Exercise 7 asks the reader to find the value which makes the range of an `unsigned long` exceed.

Change `long` to `unsigned long` and try to find the number that makes it too big.

So my approach is to first get the size of an `unsigned long` on my machine:

``printf("SIZEOF ULONG: %lu", sizeof(unsigned long)); ``

This prints `8` as a result. So assuming that an `unsigned long` will take up 64 bits on my machine I looked up the maximum range on Wikipedia.

• Unsigned: From 0 to 18,446,744,073,709,551,615

I was expecting that declaring an `unsigned long` with the above value would compile without warnings until I increment the value by 1. The result is different though. compiling the following program results in a warning.

``#include <stdio.h> int main() {     unsigned long value = 18446744073709551615;     printf("SIZEOF ULONG: %lu", sizeof(unsigned long));     printf("VALUE: %lu", value);     return 0; }  bla.c: In function ‘main’: bla.c:5:27: warning: integer constant is so large that it is unsigned      unsigned long value = 18446744073709551615;                            ^~~~~~~~~~~~~~~~~~~~ ``

So why does gcc complain about the value being to large, I thought I already declared it as `unsigned`?

Decimal integer constants have type `int` if they fit in that range, otherwise they have type `long` or `long long`. They do not have an unsigned type, and if the value is outside those signed ranges you get the warning. You need to add the `ul` suffix for the constant to have the proper type.

There’s also a much easier way to get the maximum value of this type without knowing its size. Just cast -1 to this type.

``unsigned long value = (unsigned long)-1; ``