web123456

6. The magic of type *(0)

expression type * (0)It is a common trick in C/C++ programming, usually used in kernel programming and someSystem programmingIn the scene. The main function of this syntax form is to obtain the virtual address of a specific type of pointer to obtain the0, thereby performing type conversion or performing other calculations. Next, we will analyze the specific meaning and application of this expression in depth.

1. Basic meaning of expression

  1. type * (0)

Disassembly:

  • typeis a data type (e.g.intstruct MyStructwait).
  • `` represents the pointer type, sotype *Representative totypeA pointer of type.
  • (0)is an integer constant indicating the address0, that is, the address of the null pointer.

The purpose of this expression is to create a pointertypeA pointer of type that points to an address0

For example,int * (0)Created a pointerintA pointer of type that points to a memory address0. But here does not really allocate memory, but generates aEmpty pointer

2. Why usetype * (0)

  1. Avoid real allocation of memory
    • When writing system code, developers may need to calculate through pointers or determine the offset of type members without actually allocating memory. At this timetype * (0)It came in handy. By assuming that this type of pointer is at the address0, the offset of its members relative to the starting position of the structure can be obtained, or other calculations can be performed.
  2. Type Derivation
    • This technique is often used to ensure type consistency, especially when some compile-time calculations are required using type information,type * (0)You can ensure that subsequent operations are based on the correct type.

3. Typical usage scenarios

3.1 offsetofMacro

We oftenoffsetofSeen in the implementation of macrostype * (0)How to use.offsetofThe function of a macro is to calculate a member'sStructureoffset in.

  1. #define offsetof(type, member) ((size_t)&(((type *)0)->member))

explain

  • (type *)0: Put integers0Convert to pointertypeA pointer of type, that is, assuming the structure is located at the memory address0
  • ((type *)0)->member: Accessing the structurememberMember, because the starting address of the structure is0,somemberThe address is actually its offset in the structure.
  • &(((type *)0)->member):take outmemberThe address, which is actually relative to0offset.

In this example,(type *)0No actual memory is allocated, it is just used to calculate the offset of members without creating a structure instance.

3.2 container_ofMacro

container_ofA macro is another common example, which is used to derive the first address of a structure from the pointer of a structure member:

  1. #define container_of(ptr, type, member) \\\\
  2. ((type *)((char *)(ptr) - offsetof(type, member)))

Hereoffsetof(type, member)Usedtype * (0)to calculate the offset of the member and then passptrSubtract this offset to get the starting address of the structure.

4. Detailed explanationtype * (0)Function in memory

Suppose we have a structure:

  1. struct MyStruct {
  2. int a;
  3. float b;
  4. char c;
  5. };

When we write downMyStruct *ptr = (MyStruct *)0;We didn't really assign oneMyStructAn instance of type. It's just a pointer address0The pointer, the value of the pointer is0, i.e. null pointer. This does not access any actual data in memory, but can be used to calculate the relative position of its members, e.g.ptr->bWill returnbMember relative to address0offset.

5. Calculation of pointers and offsets

type * (0)One of the core functions of this is to perform offset calculation without involving actual memory access. Here is how it helps with pointer and offset calculations:

  1. Member offset calculation:passoffsetof, the offset of the member relative to the first address of the structure can be obtained.
  2. Virtual pointer operation: Even if we do not need to allocate actual memory, we can still perform type-related operations through this virtual pointer to ensure the type safety of operations.

For example:

  1. offsetof(struct MyStruct, b)

The above macro will generate the following effects:

  1. ((size_t)&(((struct MyStruct *)0)->b))

The execution of this statement does not really access memory, but uses0The address is used as the virtual base address to calculatebexistMyStructoffset in. Through such calculations, it is possible to ensure that the program can still calculate the correct offset without an instance.

6. Things to note

  • Cannot dereference null pointer:Althoughtype * (0)Used for type inference and offset calculation, but if attempting to dereference the pointer directly (e.g.(type *)0), will cause a runtime error because it is an invalid address.
  • Type safety: When performing complex data structure operations,type * (0)Makes type-safe while calculating offsets or performing type conversions.

in conclusion

  • Function summarytype * (0)The main function is to create a pointer address0a specific type of pointer without allocating actual memory. It is usually used to calculate offsets and perform type conversion operations.
  • Typical Applicationsoffsetofandcontainer_ofare two typical usage scenarios,type * (0), the calculation and type inference of member offsets can be performed without creating actual structure instances.