Linux Device Drivers (3rd Edition) [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Linux Device Drivers (3rd Edition) [Electronic resources] - نسخه متنی

Jonathan Corbet, Greg Kroah-Hartman, Alessandro Rubini

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








11.3. Interface-Specific Types


Some of the
commonly
used data types in the kernel have
their own typedef statements, 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. We use the expression
interface-specific to refer to a type defined by
a library in order to provide an interface to a specific data
structure.

Note that, in recent times, relatively few new interface-specific
types have been defined. Use of the typedef
statement has gone out of favor among many kernel developers, who
would rather see the real type information used directly in the code,
rather than hidden behind a user-defined type. Many older
interface-specific types remain in the kernel, however, and they will
not be going away anytime soon.

Even when no interface-specific type is defined,
it's always important to use the proper data type in
a way consistent with the rest of the kernel. A jiffy count, for
instance, is always unsigned long, independent of
its actual size, so the unsigned
long type should always be used when working with
jiffies. In this section we concentrate on use of
_t types.

Many _t types are defined 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, that is
unsigned long on some platforms and
unsigned int on some others?

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 that
haven't yet been cleaned up.

The one ambiguous point
we've found in the kernel headers is data typing for
I/O functions, which is loosely defined (see the Section 9.2.6 in Chapter 9). The loose typing is
mainly there for historical reasons, but it can create problems when
writing code. For example, one can get into trouble by swapping the
arguments to functions like outb; if there were
a port_t type, the compiler would find this type
of error.


    / 202