Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
325 views
in Technique[技术] by (71.8m points)

c - list_entry in Linux

user/include/linux/list.h

this declaration:

#define list_entry(ptr, type, member) 
((type *)((char *)(ptr) – (unsigned long)(&((type *)0)->member)))

can somebody please explain what is this and how does it work, thanks in advance

P.S. please simplify your answer as much as possible, I know about threads, processes in Linux, now I'm exploring possibilities and I'm a little bit stuck with this one.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Consider two structs like this:

struct data {
    int something;
};

struct container {
    int something_before;
    struct data data_item;
    int something_after;
};

Assume you have a pointer to a struct data value:

struct data *data_ptr;

The list_entry() macro helps you to convert data_ptr to a pointer to the struct container value that holds the struct data value, pointed to by ptr:

struct container *cont_ptr = list_entry(data_ptr, struct container, data_item);

The macro works by computing the offset of data_item inside the struct container, and subtracting that many bytes from the data_ptr pointer. This, when cast to struct container *, gives a valid pointer to the struct container that holds this particular struct data "inside".

The macro can also be simplified a bit by using the builtin offsetof() macro:

#define list_entry(ptr, type, member) 
    ((type *)((char *)(ptr) – offsetof(type, member)))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...