Learn more about void and void Pointers

  • 2020-04-01 23:27:38
  • OfStack

The meaning of the void
Void is "untyped" and void * is "untyped pointer", which can point to any data type.

Void pointer usage specification
A void pointer can point to any type of data, that is, any data type of the pointer can be assigned to the void pointer. Such as:
Int * pint;
Void * pvoid;
Pvoid = pint;
If you want to assign pvoid to a pointer of another type, you need to cast the type as: pint = (int *)pvoid;


In the ANSI C standard, arithmetic operations on void Pointers such as pvoi ++ or pvoid+=1 are not allowed, but in GNU it is, because by default GNU considers void * to be the same as char *. Sizeof (*pvoid)== sizeof(char).

The role of the void
The return of the function of the limit.
The qualification of the function parameters.
Void qualification must be used when a function does not need to return a value. For example: void func(int, int);
Void qualification must be used when a function is not allowed to accept arguments. For example: int func(void).


Since a void pointer can point to data of any type, that is, a pointer of any data type can be assigned to a void pointer, a void pointer can also be used as a function parameter, so the function can accept a pointer of any data type as an argument. Such as:
Void * memcpy(void *dest, const void * SRC, size_t len);
Void * memset(void * buffer, int c, size_t num);

Many beginners do not understand the void and void pointer types in C/C++, so there are some errors in using them. This article will explain the deep meaning of the void keyword, the following details the use of void and void pointer type methods and techniques.

Rule beware of using a void pointer type
According to the ANSI (AmericanNationalStandardsInstitute), cannot algorithm on void Pointers for operation, namely the following operations are illegal:
Void * pvoid;
Pvoid++; / / ANSI: error
Pvoid + = 1; / / ANSI: error
// the ANSI standard states this because it insists that the pointer to which the algorithm operates must be certain that it knows the size of the data type to which it refers.
/ / such as:
Int * pint;
Pint++; / / ANSI: right
The result of pint++ is to make it sizeof(int).
But the famous GNU(short for GNU's notunix) disagrees, specifying that the void* algorithm operates exactly as the char*.
Therefore, the following statements are correct in the GNU compiler:
Pvoid++; / / GNU: correct
Pvoid + = 1; / / GNU: correct
The result of pvoid++ execution is that it increases by 1.
In actual programming, in order to meet the ANSI standard and improve the portability of the program, we can write code to achieve the same function like this:
Void * pvoid;
Pvoid++ (char *); //ANSI: correct; The GNU: correct
(char *) pvoid + = 1; //ANSI: error; The GNU: correct
There are some differences between GNU and ANSI; in general, GNU is more "open" than ANSI, providing more syntax support. However, we should try our best to cater to ANSI standards in real design.

Rule 2 if the argument to a function can be a pointer of any type, declare it as void*
Typical function prototypes of memcpy and memset are:
Void * memcpy (void * dest, constvoid * SRC, size_tlen);    
Void * memset (void * buffer, a steady, size_tnum);
In this way, Pointers of any type can be passed into memcpy and memset, which is also true of the memory manipulation function, because the object it operates on is just a piece of memory, regardless of the type of memory. It would be really weird if memcpy and memset took char* instead of void*! Such memcpy and memset are clearly not a "pure, tasteless" function!
The following code executes correctly:
// example: memset accepts Pointers of any type
int   Intarray [100].
Memset (intarray, 0100 * sizeof (int)); // clear the intarray to 0
// example: memcpy accepts Pointers of any type
int   Intarray1 [100].   Intarray2 [100].
Memcpy (intarray1 intarray2, 100 * sizeof (int)); // copy intarray2 to intarray1
Interestingly, the memcpy and memset functions also return the type void*. How knowledgeable the standard library function writers are!

3. Rule 3 void cannot represent a real variable
The following code attempts to make void represent a real variable, so it's all wrong code:
Voida; / / error
The function (voida); / / error
Void represents an abstraction where variables are "typed," such as a person who is either a man or a woman (and a hybrid?). .
Void exists only as an abstraction, and if you understand the concept of an "abstract base class" in object orientation correctly, it is also easy to understand the void data type. Just as we can't define an instance of an abstract base class, we can't define a void variable.


Related articles: