Interface-Specific Types

Most commonly used data types in the kernel have their own typedef statement, thus preventing any portability problems. For example, a process identifier (pid) is usually pid_t instead of int. Using pid_t masks any possible difference in the actual data typing. I use the expression ``interface-specific'' to refer to the programming interface to specific data items.

Other data items that belong to a specific ``standard'' type can be considered interface-specific as well. A jiffy count, for instance, is always unsigned long, independent of its actual size--would you like using jiffy_t every so often? I’m concentrating here on the first class of interface-specific types, the ones ending in _t.

The complete list of _t types appears in <linux/types.h>, but the list is rarely useful. When you need a specific type, you’ll find it in the prototype of the functions you need to call or in the data structures you use.

Whenever your driver uses functions that require such ``custom'' types and you don’t follow the convention, the compiler issues a warning; if you use the -Wall compiler flag and are careful to remove all the warnings, you can feel confident that your code is portable.

The main problem with _t data items is that when you need to print them, it’s not always easy to choose the right printk or printf format, and warnings you resolve on one architecture reappear on another. For example, how would you print a size_t which is unsigned long on some platforms and unsigned int on some other?

Whenever you need to print some interface-specific data, the best way to do it is by casting the value to the biggest possible type (usually long or unsigned long), and then printing it through the corresponding format. This kind of tweaking won’t generate errors or warnings because the format matches the type, and you won’t lose data bits because the cast is either a null operation or an extension of the item to a bigger data type.

In practice, the data items we’re talking about aren’t usually meant to be printed, so the issue applies only to debugging messages. Most often, the code needs only to store and compare the interface-specific types, in addition to passing them as arguments to library or kernel functions.

Although _t types are the correct solution for most situations, sometimes the right type doesn’t exist. This happens for some old interfaces, which haven’t yet been cleaned up.

The one ambiguous point I’ve found in the kernel headers is data typing for I/O functions, which is loosely defined (see the section Section 8.1.1 in Chapter 8). The loose typing is mainly there for historical reasons, but it can create problems when writing code. Personally, I often get into trouble by swapping the arguments to out functions; if port_t were defined, the compiler would pinpoint these errors.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.186.143