C22 Pointer Type Conversions
A frequent source of error in the programming of portable C applications is the false assumption that integer and pointer sizes can be typecast by means of type conversions, as in the following example:
printf("ptr before typecast: %p\n", ptr);
printf("ptr after typecast: %p\n", ptr);
The program would seem to work if the same value is returned in both outputs. However, the perfidious aspect of this example is that it functions correctly on 32-bit machines although it is actually incorrect. C does not guarantee that pointer and integer variables have the same bit length, but it happens to be the case on 32-bit systems where both integer and pointer variables require 4 bytes.
This no longer applies on 64-bit platforms where pointers require 8 bytes and integer variables still need only 4 bytes. On IA-64 systems, the sample program would produce the following output:
[email protected]> ./ptr ptr before typecast: 0x9ffffffffffff930
ptr after typecast: 0xfffffffffffff930
The values cannot be typecast without loss. Because of careless 32-bit practice, this is a source of frequent errors when converting programs to run on 64-bit architectures. The kernel source code must, of course, be 64-bit clean if it is to execute on architectures of both word lengths.
According to the C standard, programs again cannot assume that pointers and unsigned long variables can be typecast. However, because this is possible on all existing architectures, the kernel makes this assumption a prerequisite and explicitly allows type conversion as shown here:
unsigned long var; void* ptr;
Because unsigned long variables are sometimes easier to handle than void pointers, they may be typecast. This is beneficial when, for example, it is necessary to examine parts of a compound data type. With normal pointer arithmetic, var++ would cause the value to be increased by sizeof(data type). If the variable is cast into the unsigned long data type beforehand, the structure can be analyzed byte-by-byte or its contents can be traversed (this can be very useful when extracting embedded substructures).
Continue reading here: Natural Alignment
Was this article helpful?