Table of Contents

limits.h

limits.h tells you the integer type limits for the platform you are compiling on. You reach for it when you need to guard against overflow before it happens, or when you want to write code that works correctly regardless of whether long is 32 or 64 bits. Writing 2147483647 directly is asking for a silent bug the moment your code moves to a different target.

#include <limits.h>
 
INT_MAX     // max int (at least 32767; typically 2147483647 on 32-bit)
INT_MIN     // min int (typically -2147483648)
UINT_MAX    // max unsigned int
LONG_MAX    // max long (32-bit on 32-bit systems, 64-bit on 64-bit)
LLONG_MAX   // max long long: at least 9223372036854775807
CHAR_BIT    // bits per char (almost always 8)
UCHAR_MAX   // max unsigned char (255 on 8-bit char)

The right way to check for overflow before it happens:

// safe addition: check the headroom first
if (a > INT_MAX - b)
    /* would overflow */;
else
    result = a + b;

For fixed-width types (uint32_t, etc.), the limits come from <stdint.h>UINT32_MAX, INT32_MIN, and so on. <limits.h> covers the standard named types only.

Practice

// compile: gcc -o lim lim.c
// run: ./lim     try on 32-bit and 64-bit and compare LONG_MAX
// description: print integer limits and demonstrate unsigned wraparound
 
#include <limits.h>
#include <stdio.h>
 
int main(void) {
    printf("CHAR_BIT  = %d\n",   CHAR_BIT);
    printf("INT_MAX   = %d\n",   INT_MAX);
    printf("UINT_MAX  = %u\n",   UINT_MAX);
    printf("LONG_MAX  = %ld\n",  LONG_MAX);
    printf("LLONG_MAX = %lld\n", LLONG_MAX);
 
    // unsigned overflow wraps to 0 — this is defined behaviour
    unsigned int u = UINT_MAX;
    printf("UINT_MAX + 1 = %u\n", u + 1);  // 0
 
    // signed overflow is undefined — check first
    int a = INT_MAX, b = 1;
    if (a > INT_MAX - b)
        puts("INT_MAX + 1 would overflow — caught it");
    return 0;
}

Run this on a 32-bit and a 64-bit machine and compare LONG_MAX. On 32-bit Linux it will be 2147483647; on 64-bit it will be 9223372036854775807. That difference is exactly why you should never hardcode the max value of long.