Type Sizes & limits.h
Because C only guarantees minimum sizes for its built-in types, any code that cares about exact ranges or byte counts needs a reliable way to check them on the platform it is actually compiled for, rather than assuming a fixed size. C gives you two tools for this: the sizeof operator, and the constants defined in <limits.h> and <float.h>.
sizeof — checking actual sizes
sizeof is a compile-time operator that returns the size, in bytes, of a type or expression, as an unsigned value of type size_t. It works on both fundamental types and your own structs and arrays.
#include <stdio.h>
int main(void) {
printf("sizeof(char) = %zu\n", sizeof(char));
printf("sizeof(short) = %zu\n", sizeof(short));
printf("sizeof(int) = %zu\n", sizeof(int));
printf("sizeof(long) = %zu\n", sizeof(long));
printf("sizeof(long long) = %zu\n", sizeof(long long));
printf("sizeof(float) = %zu\n", sizeof(float));
printf("sizeof(double) = %zu\n", sizeof(double));
return 0;
}sizeof(char) = 1 sizeof(short) = 2 sizeof(int) = 4 sizeof(long) = 8 sizeof(long long) = 8 sizeof(float) = 4 sizeof(double) = 8
<limits.h> — integer range constants
Rather than hard-coding what you assume the min/max of a type to be, <limits.h> provides named constants that the compiler fills in correctly for its own platform, giving you portable range checks.
Constant | Meaning |
|---|---|
| Number of bits in a byte (almost always 8) |
| Minimum and maximum value of |
| Maximum value of |
| Minimum and maximum value of |
| Minimum and maximum value of |
| Range of |
#include <stdio.h>
#include <limits.h>
int main(void) {
printf("CHAR_BIT = %d\n", CHAR_BIT);
printf("INT_MIN = %d\n", INT_MIN);
printf("INT_MAX = %d\n", INT_MAX);
printf("LONG_MAX = %ld\n", LONG_MAX);
return 0;
}CHAR_BIT = 8 INT_MIN = -2147483648 INT_MAX = 2147483647 LONG_MAX = 9223372036854775807
<float.h> — floating-point limits
The floating-point equivalent of <limits.h> is <float.h>, which exposes constants describing the precision and range of float, double, and long double on the current platform, such as FLT_MAX, DBL_MAX, FLT_EPSILON, and DBL_DIG (the number of reliably representable decimal digits).
#include <stdio.h>
#include <float.h>
int main(void) {
printf("FLT_MAX = %e\n", FLT_MAX);
printf("DBL_MAX = %e\n", DBL_MAX);
printf("FLT_EPSILON = %e\n", FLT_EPSILON);
return 0;
}Don't hard-code assumed sizes
Use
sizeof(type)to find the actual size of a type on the current platform at compile time.%zuis the correct printf conversion for thesize_tvaluesizeofreturns.<limits.h>provides portable integer range constants likeINT_MAXandCHAR_BIT.<float.h>provides the floating-point equivalents, likeFLT_MAXandDBL_EPSILON.Never hard-code an assumed type size — it is a classic source of portability bugs.