Linux Kernel Architecture

(Jacob Rumans) #1
Mauerer app03.tex V1 - 09/04/2008 6:11pm Page 1201

Appendix C: Notes on C


help of a hash table in which all existing instances are arranged), a pointer to the instance is returned
after the usage counter has been incremented.

The instance is not returned by simply freeing the memory space. Instead, this task is delegated to a
function that first checks whether the usage counter is greater than 1. If it is, the instance is still required
in other parts of the kernel, and the counter is decremented by 1. Only when the counter is decremented
to 0 (it is 1 when the function is started) can the memory space occupied by the data structure be returned
to memory management because the instance is no longer in use.

C.2.2 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:

int var;
void *ptr = &var;

printf("ptr before typecast: %p\n", ptr);

var = (int)ptr;
ptr = (void*)var;

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 correctlyon 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:

wolfgang@64meitner>./ptr
ptr before typecast: 0x9ffffffffffff930
ptr after typecast: 0xfffffffffffff930

The values cannot be typecast withoutloss. 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 andunsigned longvariables
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;

var = (unsigned long)ptr;
ptr = (void*)var;

Becauseunsigned longvariables are sometimes easier to handle thanvoidpointers, they may be type-
cast. This is beneficial when, for example, it is necessary to examine parts of a compound data type. With
Free download pdf