Difference between LIST_HEAD_INIT and INIT_LIST_HEAD

c, linked-list, linux-kernel

Solution

A quick LXR search shows:

#define LIST_HEAD_INIT(name) { &(name), &(name) }

static inline void INIT_LIST_HEAD(struct list_head *list)
{
        list->next = list;
        list->prev = list;
}

So `INIT_LIST_HEAD` gets a `struct list_head *` and initializes it, while `LIST_HEAD_INIT` returns the address of the passed pointer in a suitable fashioned for use as an initializer for a list:

struct list_head lst1;
/* .... */
INIT_LIST_HEAD(&lst1);



struct list_head lst2 = LIST_HEAD_INIT(lst2);

Problem

I'm trying to understand the Linux kernel linked list API. According to Linux Kernel Linked List I should initialize the list head by `INIT_LIST_HEAD` but here (Linux Kernel Program) it's suggested to use `LIST_HEAD_INIT` instead. Here's a working code I wrote, but I'm not sure if I did it in proper way. Could someone verify that it's OK? ``` #include <stdio.h> #include <stdlib.h> #include "list.h" typedef struct edge_attr { int d; struct list_head list; } edge_attributes_t; typedef struct edge { int id; edge_attributes_t *attributes; } edge_t; int main () { int i; struct list_head *pos; edge_attributes_t *elem; edge_t *a = (edge_t*)malloc(sizeof(edge_t)); a->id = 12; a->attributes = (edge_attributes_t*) malloc(sizeof(edge_attributes_t)); INIT_LIST_HEAD(&a->attributes->list); for (i=0; i<5; ++i) { elem = (edge_attributes_t*)malloc(sizeof(edge_attributes_t)); elem->d = i; list_add(&elem->list, &a->attributes->list); } list_for_each(pos, &(a->attributes->list)) { elem = list_entry(pos, edge_attributes_t, list); printf("%d \n", elem->d); } return 0; } ```

Original source