I'm reading linux/list.h
header, it have this macro:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
I want to know when I write LIST_HEAD_INIT(birthday_list)
how the macro expanded?
The ampersand can be used to indicate that the "and" in a listed item is a part of the item's name and not a separator (e.g. "Rock, pop, rhythm & blues and hip hop"). The ampersand may still be used as an abbreviation for "and" in informal writing regardless of how "and" is used.
The ampersand symbol & is used in C++ as a reference declarator in addition to being the address operator. The meanings are related but not identical. If you take the address of a reference, it returns the address of its target. Using the previous declarations, &rTarg is the same memory address as &target .
In C++ type declarations, the ampersand means "reference". In this case operator << returns a reference to an ostream object.
Macros and its types in C/C++ A macro is a piece of code in a program that is replaced by the value of the macro. Macro is defined by #define directive. Whenever a macro name is encountered by the compiler, it replaces the name with the definition of the macro.
LIST_HEAD_INIT is used to initialize the list head structure instance.
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
from linux/types.h:
struct list_head {
struct list_head *next, *prev;
};
This is expanded to
struct list_head name = { &(name), &(name) }
As you can see, it is expanded and now the "prev" and "next" pointers fields of structure instance "name" points back to itself. This is how the list head is initialized.
After intialization LIST_HEAD(birthday_list) is birthday_list.prev = birthday_list.next = &birthday_list "birthday_list" is the head node of the double linklist which is empty and instead of leaving the prev and next pointer to NULL, they have been set to point back to the head node.
struct list_head birthday_list = {
.next = &birthday_list,
.prev = &birthday_list
}
There's nothing special about ampersands, they're just another token. LIST_HEAD_INIT(birthday_list)
gets expanded as { &(birthday_list), &(birthday_list) }
You can just look at the output of the preprocessor directly if you want to check this or other macro expansions yourself. GCC has the -E argument to do this.
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