In C, the size of basic types (char, signed int, unsigned int, float, double, and long double) is implementation-defined, so relying on a particular data type to be a given size reduces the portability of a program.
Summary: Don't make assumptions about the size of data types.
Because the size of basic types is left to the implementation, do not make assumptions about the size or alignment of data types within aggregate types. Use only the sizeof operator to determine the size or amount of storage required for a variable or a type.
Following are some rules governing the size of data types.
Type char is the smallest of the basic types, but it must be large enough to hold any of the characters in the implementation's basic character set. Normally, variables of type char are one byte.
Type int often corresponds to the register size of the target machine. Type short int may be less than or equal to the size of type int. Both int and short are greater than or equal to the size of type char but less than or equal to the size of type long.
If you assume that type int is a certain size, your code may not be portable because
An int can be defined as a 16-bit (two-byte) or a 32-bit quantity.
An int is not always large enough to hold array indexes. For large arrays, you must use unsigned int; for extremely large arrays, use long or unsigned long. To be certain your code is portable, define your array indexes as type size_t. You may not know, before porting your code, the maximum value to expect an array index of type int to hold. The file LIMITS.H contains manifest constants, listed below, for the maximum and minimum values of each basic integral type.
Constant | Value |
CHAR_BIT | Number of bits in a variable of type char |
CHAR_MIN | Minimum value a variable of type char can hold |
CHAR_MAX | Maximum value a variable of type char can hold |
SCHAR_MIN | Minimum value a variable of type signed char can hold |
SCHAR_MAX | Maximum value a variable of type signed char can hold |
UCHAR_MAX | Maximum value a variable of type unsigned char can hold |
SHRT_MIN | Minimum value a variable of type short can hold |
SHRT_MAX | Maximum value a variable of type short can hold |
USHRT_MAX | Maximum value a variable of type unsigned short can hold |
INT_MIN | Minimum value a variable of type int can hold |
INT_MAX | Maximum value a variable of type int can hold |
UINT_MAX | Maximum value a variable of type unsigned int can hold |
LONG_MIN | Minimum value a variable of type long can hold |
LONG_MAX | Maximum value a variable of type long can hold |
ULONG_MAX | Maximum value a variable of type unsigned long can hold |
Type float, Type double, and Type long double
Type float is the smallest of the basic floating-point types. Type double is usually larger than type float, and type long double is usually the largest of the floating-point types. You can make the following portability assumptions about floating-point types:
Any value that can be represented as type float can be represented as type double (type float is a subset of type double).
Any value that can be represented as type double can be represented as type long double (type double is a subset of type long double).
The file FLOAT.H contains manifest constants, listed below, for the maximum and minimum values of each basic floating-point type.
Constant | Value |
DBL_DIG | Number of decimal digits of precision a variable of type double can hold |
DBL_MAX | Maximum value a variable of type double can hold |
DBL_MAX_10_EXP | Maximum value (base 10) the exponent of a variable of type double can hold |
DBL_MAX_EXP | Maximum value (base 2) the exponent of a variable of type double can hold |
DBL_MIN | Minimum positive value a variable of type double can hold |
DBL_MIN_10_EXP | Minimum value (base 10) the exponent of a variable of type double can hold |
DBL_MIN_EXP | Minimum value (base 2) the exponent of a variable of type double can hold |
FLT_DIG | Number of decimal digits of precision a variable of type float can hold |
FLT_MAX | Maximum value a variable of type float can hold |
FLT_MAX_10_EXP | Maximum value (base 10) the exponent of a variable of type float can hold |
FLT_MAX_EXP | Maximum value (base 2) the exponent of a variable of type float can hold |
FLT_MIN | Minimum positive value a variable of type float can hold |
FLT_MIN_10_EXP | Minimum value (base 10) the exponent of a variable of type float can hold |
FLT_MIN_EXP | Minimum value (base 2) the exponent of a variable of type float can hold |
LDBL_DIG | Number of decimal digits of precision a variable of type long double can hold |
LDBL_MAX | Maximum value a variable of type long double can hold |
LDBL_MAX_10_EXP | Maximum value (base 10) the exponent of a variable of type long double can hold |
LDBL_MAX_EXP | Maximum value (base 2) the exponent of a variable of type long double can hold |
LDBL_MIN | Minimum positive value a variable of type long double can hold |
LDBL_MIN_10_EXP | Minimum value (base 10) the exponent of a variable of type long double can hold |
LDBL_MIN_EXP | Minimum value (base 2) the exponent of a variable of type long double can hold |
Table 12.1 summarizes the size of the basic types in Microsoft C.
Table 12.1 Size of Basic Types in Microsoft C
Type | Number of Bytes |
char, unsigned char | 1 |
short, unsigned short | 2 |
int, unsigned int | 2 or 4* |
near pointer | 2 or 4* |
long, unsigned long | 4 |
far pointer | 4 or 8* |
float | 4 |
double | 8 |
long double | 10 |
* These data types have different sizes in 16- and 32-bit environments.