1. The specific code and analysis are as follows
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stddef.h>
/* Use a hypothetical structure at address 0 to get the offset of member */
#define OffsetOf(type,member) ( (unsigned int)&((type*)0)->member )
#if 0 /* typeof is an extension keyword of GCC compiler, mainly used to get the type of a variable or expression at compile time */
/* Calculate the address of the structure variable through the address of member in struct type, that is, find the address of the structure through the member */
#define ContainerOf(ptr,type,member) \({ \ const typeof( ((type*)0)->member )* __mptr = (ptr); \ (type*)( (char*)__mptr - OffsetOf(type,member) ); \})
#endif
/* The simplest ContainerOf macro, removing typeof */
#define ContainerOf(ptr, type, member) \ ((type*)((char*)(ptr) - OffsetOf(type, member)))
typedef struct Person{int age; char name[20];double height;}Person;
int main(){ Person person; person.age = 29;
strcpy(person.name, "112233");
person.height = 169.5;
unsigned int ageOffset = OffsetOf(Person, age); //0
unsigned int nameOffset = OffsetOf(Person, name); //4
unsigned int heightOffset = OffsetOf(Person, height); //24
char* temp = (char*)&person;/* Output 0x008FF900 */
printf(":%p\n", temp);/* Output 0x008FF900 */
printf(":%p\n", &person);
// Get structure address through different members Person* from_age = ContainerOf(&person.age, Person, age); Person* from_name = ContainerOf(person.name, Person, name); Person* height = ContainerOf(&person.height, Person, height);
/* Output 0x008FF900 */
printf("Calculated through age: %p\n", from_age);
/* Output 0x008FF900 */
printf("Calculated through name: %p\n", from_name);
/* Output 0x008FF900 */
printf("Calculated through height: %p\n", height);
temp = NULL;}
2. Testing Platform
VS2015