I generally have ignored using macros while writing in C but I think I know fundamentals about them. While I was reading the source code of list in linux kernel, I saw something like that:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
(You can access the remaining part of the code from here.)
I didn't understand the function of ampersands(I don't think they are the address of operands here) in LIST_HEAD_INIT and so the use of LIST_HEAD_INIT in the code. I'd appreciate if someone can enlighten me.
The LENGTH and BREADTH are called the macro templates. The values 10 and 20 are called macro expansions. When the program run and if the C preprocessor sees an instance of a macro within the program code, it will do the macro expansion. It replaces the macro template with the value of macro expansion.
More Linux resources In Vim, a macro is a feature that allows you to record a sequence of commands that you use to perform a given task. You then execute that macro many times to repeat the same job in an automated way.
Macro expansion is an integral part of eval and compile . Users can also expand macros at the REPL prompt via the expand REPL command; See Compile Commands. Macros can also be expanded programmatically, via macroexpand , but the details get a bit hairy for two reasons. The second complication involves eval-when .
In computer programming, a macro (short for "macro instruction"; from Greek μακρο- 'long, large') is a rule or pattern that specifies how a certain input should be mapped to a replacement output. Applying a macro to an input is known as macro expansion.
To know what actually is happening we need the definition of struct list_head
:
struct list_head {
struct list_head *next, *prev;
};
Now consider the macros:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
If in the code I write LIST_HEAD(foo)
it gets expanded to:
struct list_head foo = { &(foo) , &(foo)}
which represents an empty doubly linked list with a header node where the next
and prev
pointers point to the header node itself.
It is same as doing:
struct list_head foo;
foo.next = &foo;
foo.prev = &foo;
So effectively these macros provide a way to initialize a doubly linked list.
And yes, &
is used here as the address of operator.
EDIT:
Here is a working example
In the link provided by you. You had:
struct list_head test = LIST_HEAD (check);
which is incorrect. You should have:
LIST_HEAD (check);
Every time you're in doubt on what macro is actually doing, you can ask 'gcc -E' to expand it for you.
In this case it just initialise a list structure with pointers to itself.
They are address-of operators here. The linked lists in the kernel avoid null pointers to denote the end of a list. Therefore, the header must be initialized with some valid pointer. In this implementation, if the "head" or "tail" pointer point to the address of the list header, the list is considered empty.
The macro itself seems to be not used in the list.h
.
I assume &
mean indeed addresses in the code. The struct list_head
contains two pointers, so it should be quite natural for declaration struct list_head name = LIST_HEAD_INIT(name)
(see macro LIST_HEAD
) to obtain a pair of pointers as initializer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With