Test you: reverse push the first address of the struct according to the variable address of the struct.

Source: Internet
Author: User

[Question ]:
Calculate the first address of a struct object based on the address of a member.
[Example ]:
Struct
{
Int x;
Int y;
Int z;
}
 
# Define GET_HEADER_ADDR (MEMBER) (you can implement it)
 
Void main ()
{
Struct A myTest;
 
Printf ("addr is % d", GET_HEADER_ADDR (myTest. z ));
 
}
Let's not look at the answer below. Let's try to implement the macro above.
 

[Answer and analysis process]
In the Linux kernel, two very clever macros are used for implementation. One is the offsetof macro and the other is the container_of macro. The two macros are described below.
1. offsetof macro
[Definition]: # define offsetof (TYPE, MEMBER) (size_t) & (TYPE *) 0)-> MEMBER)
[Function]: obtains the offset of a struct variable Member in this struct.
[Example ]:
Struct
{
Int x;
Int y;
Int z;
};
 
Void main ()
{
Printf ("the offset of z is % d", offsetof (struct A, z ));
}
 
// The output result is 8.
[Analysis ]:
 
The Macro, TYPE is the struct TYPE, and MEMBER is the variable name in the structure.
 
(TYPE *) 0) indicates that the spoofing compiler has a pointer to the structure TYPE, and its address value is 0.
 
(TYPE *) 0)-> MEMBER is the address for obtaining the MEMBER variable MEMBER in the struct TYPE. because the base address is 0, the MEMBER Address is of course the offset of MEMBER in TYPE.
 
2. container_of macro (that is, the function in the question is implemented)
 
[Definition ]:
 
# Define container_of (ptr, type, member) ({const typeof (type *) 0)-> member) * _ mptr = (ptr); (type *) (char *) _ mptr-offsetof (type, member ));})
 
[Function ]:
 
Obtain the first pointer of a struct (type) from a member variable (member) pointer (ptr.
 
[Example ]:

Struct
{
Int x;
Int y;
Int z;
};
 
Struct A myTest;
 
Int * pz = myTest. z;
 
Struct A * getHeaderPtr (int * pz)
{
Return container_of (pz, struct A, z );
}

[Analysis ]:
(1) typeof (type *) 0)-> member) is the variable type used to retrieve members of member.

(2) define _ mptr pointer ptr as the pointer to the member variable (that is, to the variable pointed to by ptr)

(3) (char *) _ mptr-offsetof (type, member) use the actual address of the member variable minus the offset of the variable in the struct to find the starting address of the struct.

(4) ({}) The extension returns the value of the last expression in the program block.
 
This article is from the "three shadows" blog

Related Article

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.