Linux Kernel Architecture

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

Appendix C: Notes on C


The program produces the following output:

wolfgang@meitner>and
And and

Because both numbers have no matching bit values at any bit position, bitwise AND returns 0 as
its result.

If 4 and 5 are used as input instead, both operators return a true value because the bits at position 2 in
both numbers are equal to 1 — in any case, both are greater than 0 (for&&).

The moral of the story (and please excuse the word play) is that AND and AND AND^8 are not always
the same.

Finally, notice that the kernel defines the auxiliary functionDECLARE_BITMAPto create a bitmap with
sufficient space to store the number of bits given by thebitsparameter:

<types.h>
#define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]

The macro automatically computes the required number oflongs in the array such that sufficient space
for all bits is available.

C.2.5 Pre-Processor Tricks


Most programmers are familiar with the pre-processor. However, the kernel uses two constructions that
are not usually needed and are therefore worthy of discussion.

Macro arguments that occur within strings are normally not replaced. If a string is to be generated from
a parameter, it is necessary to use a special pre-processor function known asstringification.Arguments
within strings that are to be replaced with their macro parameters must be prefixed by a hash mark, as in
the following example:

#define warning(text)\
printf("Warning: " #text "\n")

If the macro is used as follows:

warning(foobar not found);

the pre-processor generates the following output:

printf("Warning: " "foobar not found" "\n");

If functions (whose names are to be specified in part by macro parameters) are defined with the help of
the pre-processor, it is necessary to make use of the (concatenation) capability of the pre-processor. This
is illustrated by the following example used in the kernel to define functions for port IO with various
data types. Two hash marks are used to merge two consecutive tokens into a compound token once all
pre-processor replacements have been carried out.

(^8) Which reminds of the PL/I constructIF IF = THEN THEN THEN = ELSE ELSE ELSE = IF;.

Free download pdf