Detailed explanation of structure address--list_entry () by struct member address calculation

Source: Internet
Author: User

 
   
  
  1. #define list_entry(ptr, type, member) container_of(ptr, type, member)
when we are programming, we often look for the address of one of the members in the case where we know the address of the struct, but if we know the address of the member, if we find the corresponding address of the struct? in the Linux kernel, the function that gets the address of the node is List_entry (), and its macro definition is as shown above.
let's look at the definition of container_of (PTR, type, member) and find that it remains a macro definition:
  
 
  1. #define container_of(ptr, type, member) \
  2. ({ \
  3. const typeof(((type *)0)->member) * __mptr = (ptr); \
  4. (type *)((char *)__mptr - offsetof(type, member)); \
  5. })
Incontainer_of (PTR, type, member) in the macro definition, the true return node address is the last word,and in the last word,offsetof (TYPE, MEMBER) is still a macro definition.
 
   
  
  1. #define ( type MEMBER ) size_t Span class= "pun") & (( type *) 0 member )
 
   
  
  1. typedef __kernel_size_tsize_t;
  2. typedef unsigned int__kernel_size_t;
By looking through the layers we'll talk about the concrete implementation of the List_entry () function, and we'll start with the bottom up.

    1.    
           
          
      1. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
    • TYPE
This is our custom struct type, with at least one List_head member variable inside it, as follows:
  
 
    1. < Code class= "Language-cpp" >struct TYPR
    2. {
    3. //...
    4. struct List_head member
    5. Span class= "com" >//...
    6. };
Where List_head is also a struct, the definition of which we'll talk about later.
    • MEMBER
This is the variable name of the type List_head variable in the type object.
    • Statement parsing
(TYPE *) 0: Cast 0 To type pointer, the pointer must point to the 0 address (the data segment base). & ((TYPE *) 0)->member This sentence is actually& (((TYPE *) 0)->member),using this pointer to access the type'smember members and get their addresses. Since the starting address of this pointer is 0, then& ((TYPE *) 0)->member is the starting address of a type variablewith the variable internalmember The offset between the starting address of the member variable, which is true for all type variables. So, the next idea is clear, we just need to know a type variablemember The starting address of the variable, minusOffsetof (Type, MEMBER) This offset, you can get the start address of the type variable.
The correspondence of it is as follows:

The idea is clear, but there are some details that need attention, and we continue to look at the code.
2.
  
 
  1. #define container_of(ptr, type, member) \
  2. ({ \
  3. Span class= "KWD" >const typeof (( type *) 0 member ) * __mptr = ( ptr \
  4. (type *)((char *)__mptr - offsetof(type, member)); \
  5. })
    • Const typeof (((type *) 0)->member) * __mptr = (PTR);
Since we're going to force type conversions on pointers, here we apply a pointer to the same position as PTR. The PTR here refers to the actual address of the List_head member.
    • (char *) __mptr
Since the Offsetof () function evaluates the number of offset bytes, here(char *) __MPTR allows the pointer to add and subtract operation step 1ByteThe starting address of the type variable can then be subtracted and finally passed(Type *) type conversion, which translates the address to a pointer of type. and then up is some macro definition there's nothing to say.





































From for notes (Wiz)

Detailed explanation of structure address--list_entry () by struct member address calculation

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.