Pointer size depends on a lot of factors (hardware, operating system, compiler, etc.), and not all pointer types on the same platform may have the same size. For example, there are embedded processors that use a Harvard architecture, where code and data are in separate memory areas, and each may have a different bus size (e.g., 8 bits for data, 16 bits for code). This means that object pointers (int *
, char *
, double *
) may be 8 bits wide, but function pointers (int (*)()
) may be 16 bits wide.
For another example, consider a word-addressed architecture, where the basic unit of memory is not an 8-bit byte, but a larger unit (where the width can be 16, 18, 24, 32, 36, 64, or 128 bits, or some other value; powers of 2 have proven to be convenient, but not necessary). Some of these architectures may choose to pack multiple char
values into a single word, meaning that a char *
needs a few extra bits to specify an offset into the word.
In the book C: A Reference Manual, Harbison & Steele describe an architecture with 36-bit words. Character data were stored as 7-bit ASCII values, meaning each word could hold 5 characters with one bit unused; all other types took up full words.