Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the application of ampersand within C macros?

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?

like image 551
Milad Khajavi Avatar asked Jan 11 '14 06:01

Milad Khajavi


People also ask

What is the function of ampersand?

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.

What is the use of ampersand in C++?

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 .

What does ampersand after type mean in C++?

In C++ type declarations, the ampersand means "reference". In this case operator << returns a reference to an ostream object.

What is in C macro?

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.


2 Answers

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
}
like image 51
Vikram Singh Avatar answered Nov 02 '22 23:11

Vikram Singh


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.

like image 35
bames53 Avatar answered Nov 02 '22 23:11

bames53