Void * in C and C++
In the C and C++ programming languages, the keyword "void*" is used to represent a pointer to an object of an unknown type. However, how this keyword is used and the implications of using it can differ between the two languages.
Void * in C:
In C, void* is primarily used as a generic pointer type. This means that a variable of type void* can hold the address of any type of object, including variables of other pointer types. For example:
int x = 5;
void* ptr = &x; //ptr now holds the address of the variable x
Here, we have defined a variable x of type int and a pointer variable ptr of type void*. We have assigned the address of variable x to the pointer variable ptr.
This feature is often used in C when working with function pointers, where the exact type of the function being pointed to is not known at compile time.
Void * in C++:
In C++, void* also serves as a generic pointer type, but it also has additional uses. One key difference between C and C++ is that C++ supports object-oriented programming, which allows for creating classes and objects. In C++, void* can be used as a base class for other classes, allowing for the creation of objects of unknown type. This feature is often used in C++ when working with templates, where the exact type of the object being pointed to is unknown at compile time.
Use of void * in Function Pointers:
void func1(){printf("Hello from func1");}
void func2(){printf("Hello from func2");}
void (*fptr)(); //fptr is a pointer to a function that returns void and takes no arguments
fptr = func1; // Assign the address of func1 to fptr
fptr(); // calls the function pointed to by fptr, i.e. func1
fptr = func2;
fptr();// calls the function pointed to by fptr, i.e. func2
The above code is a C code snippet demonstrating the use of function pointers. It contains three parts.
- First, two functions are defined: func1 and func2. These are both void functions, meaning they do not return a value, and they take no arguments. They both print a different message to the console.
- Next, a function pointer variable named fptr is defined. The syntax void (*fptr)() defines a pointer variable named fptr which can hold the address of a function that returns void and takes no arguments.
- Finally, the address of func1 is assigned to fptr, and then the function pointed to by fptr is called. This causes the message "Hello from func1" to be printed to the console. Then the address of func2 is assigned to fptr, and again the function pointed to by fptr is called, this causes the message "Hello from func2" to be printed to the console.
This code demonstrates how function pointers can call different functions at different times by simply changing the function it points to.
Function pointers are a powerful feature in C and C++ and are often used in cases where the exact function to be called is not known at compile-time and needs to be determined at runtime.
Use of void* in Templates:
template<typename T>
class A {
T* ptr;
public:
A(T* p) : ptr(p) {}
void fun() {
cout << *ptr;
}
};
int x = 5;
A<int> obj(&x);
obj.fun();
Here, we have created a class template A, where T is the type of the object, and we have defined a pointer of type T in the class. In the constructor, we are passing the address of an int variable x. When we create an object of class A with int type, the constructor gets executed, and the pointer gets the address of x.
Dereferencing void* pointers in C and C++:
Another difference between the two languages is that, in C, void* pointers cannot be dereferenced, meaning you cannot use the * operator to access the value stored at the memory location pointed to by a void* pointer.
int x = 5;
void* ptr = &x;
printf("%d",*ptr); //compile-time error
This is because the compiler has no way of knowing the type of object stored at that memory location and, therefore, cannot generate the appropriate code to access it. In contrast, in C++, void* pointers can be dereferenced, but only by explicitly casting them to a specific type.
int x = 5;
void* ptr = &x;
printf("%d",*(int*)ptr); //output: 5
Arithmetical manipulation of void* pointers in C and C++:
One more difference between the two languages is that, in C, void* pointers cannot be arithmetically manipulated. This is because, without knowing the size of the object pointed to, the compiler cannot know how much to increment or decrement the pointer by.
int x = 5;
void* ptr = &x;
ptr++; //compile-time error
In contrast, in C++, void* pointers can be arithmetically manipulated, but again, only by explicitly casting them to a specific type.
int x = 5;
void* ptr = &x;
ptr = (int*)ptr + 1;
Conclusion:
While void* is a keyword that is used in both C and C++ to represent a pointer to an object of unknown type, how it is used and the implications of using it can differ between the two languages.
In C, void* is primarily used as a generic pointer type, but it cannot be dereferenced or arithmetically manipulated. In C++, void* serves as a generic pointer type, but it can also be used as a base class for other classes and can be dereferenced and arithmetically manipulated, but only by explicitly casting them to a specific type.
It's worth noting that, generally, the use of void* should be avoided where possible, as it can make code more difficult to understand and maintain. In C, for example, it can be better to use function pointers with specific types rather than void*. In C++, it can be better to use templates, rather than void*, to create objects of unknown type.