contributed by < tommywang0tw
>
Before the compiler compiles a program, the pre-processor expands all the macros in the code by simply replacing the name of macros by its value. On the other hand, the code of functions stay unchanged before compilation. Functions are implemented by storing the current address of instruction into the stack and jump to the function when a function is called. Then the address is poped and pointed by the program counter again after the function returns.
Instead of function call, we prefer to use macro when a short part of code is highly frequently used. By doing this, we don't need to keep calling a stack to store the address of current instruction so that the program can run faster and save space for the stack and pointers.
In the file linux.h, so many macros are used. For example:
The macro above can visit each node in the linked-list. It's a short one-line code and very simple function. I searched "list_for_each" in the linux kernel, it is used in 249 code. And it's used many times in each file(more than 10 times in some of them).
to be continued…
typeof
can refer a type of a expression or just simply a type.
In the reference link, I don't get this:
typeof (x[0](1))
The description is:This assumes that x is an array of pointers to functions; the type described is that of the values of the functions.
For example:
This declares y with the type of what x points to. If x is declared as: int * x
, y will have the int type.
Another example:
The declartion above is equal to this simple one:
The use of typeof
can improve the compability of a code. Think about this, if we implement a function or macro, we would want it can be used for any type of input. In this case, typeof
can help and make our code be reusable for many other situations.
For example, in include/linux/typecheck.h, the macro below can check if a variable x
has the type of type
:
If there were no typeof
, different typecheck macros would probably be needed for different types.
I don't get how exactly this code works. I can understand __dummy
and __dummy2
would have the same type if x has the type of type
. However, the expression in line 4 is so confusing. Here is my understanding so far:
In line 2 and 3, we declare two variables called __dummy
and __dummy2
. Then &__dummy
is the address of operator __dummy
. __dummy
and __dummy2
are two variables have their own address, so their address must not be the same. In this case, the expression in line 4 will always be false. Moreover, I don't know why the parentheses are used like this ({…}), and why there is only a 1
in line 5.
check GNU extension in gcc manual
Here is another example, it's a very commonly-used macro in linux kernel called container_of
.
This macro is
struct list_head
In this code, the head and nodes attached to it share the same struct type. If this list is empty, the @prev and @next of head will just point to head itself. If it's not, @prev will point to the last node and @next will point to the first one. The declartion is in list.h
and is shown below:
struct listitem
In struct list_head
, there wasn't an element to store the value of a node. I found another structure in common.h
, and this declaration clarifies how the value is stored. This structure listitem
has two elements, one is the value of the node, and another one is a list_head structure we just discussed. In common.h
:
container_of
__extension__
?-pedantic
option causes warnings for many GNU C extensions. We can prevent such warnings within one expression by writing __extension__
before the expression. __extension
has no effect aside from this
__
? e.g. __inline__
, __typeof__
, etc.When -ansi
or std
options are used, certain keywords in GNU C extensions are disabled. The way to solve the problem is put double underscores __
at the beginning and the end of each keyword. e.g. __asm__
, __inline__
.
to be continued…