Magic Macro Container_of ()

Source: Internet
Author: User
content translation from http://radek.io/2012/11/10/magical-container_of-macro/

When you start reading the code for the Linux kernel, you end up with this magical macro.
What does this macro do?

three parameters : PTR, Type,member, respectively: Member of the pointer, containing the type of container for this member, the name of this member

return value: A pointer to the container containing the member, as shown below

This macro is useful when you know the name and the pointer of a member and want to find a pointer to its own structure (nonsense). For example, when using the C language to write a highly adaptable linked list

How this macro is implemented.

#define CONTAINER_OF (PTR, type, member) ({                      \
        const typeof ((type *) 0)->member) *__mptr = (PTR);    \
        (Type *) ((char *) __mptr-offsetof (Type,member));}

The next step is to explain declaration/Statement in an expression

GNU has an extension to the C language, the value of the entire expression in the name Braced-group within expression,{} is the last declared value. The compiler evaluates evaluate entire {}, with the last declaration/statement as the value of the entire expression.

The following example results in a 5

int x = ({1; 2;}) + 3;
printf ("%d\n", X);

typeof ()

This is a nonstandard GNU C extension. Returns the type of a unique parameter. The semantics of this macro are in http://gcc.gnu.org/onlinedocs/gcc/Typeof.html with the specific description

int x = 5;
typeof (x) y = 6;
printf ("%d%d\n", x, y);

The solution that references the 0 pointer gets the type of the member of the 0 pointer or takes the address of the member does not crash. Because an expression is not evaluated, the compiler cares only about the type. When the member address is taken, the offset address in the structure body is removed.

struct S {
        char M1;
        char m2;
};

/* This'll print 1
/printf ("%d\n", & ((struct s*) 0)->m2);

The following two definitions are equivalent

typeof (((struct S *) 0)->m2) C;
char c;

Offsetof (St, M) its implementation method has been mentioned above. This macro is in stddef.h and is part of the standard library. But the kernel has no standard library, and the following is the kernel (messy) implementation

#define OFFSETOF (Type, member) ((size_t) & ((type *) 0)->member)

Returns the offset position in the type struct body of the name member. put together

#define CONTAINER_OF (PTR, type, member) ({                      \
        const typeof ((type *) 0)->member) *__mptr = (PTR);    \
        (Type *) ((char *) __mptr-offsetof (Type,member));}

Combined above already very easy to understand

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.