Is there a legitimate use for void*?
Is there a legitimate use of void*
in C++? Or was this introduced because C had it?
Just to recap my thoughts:
Input: If we want to allow multiple input types we can overload functions and methods, alternatively we can define a common base class, or template (thanks for mentioning this in the answers). In both cases the code get's more descriptive and less error prone (provided the base class is implemented in a sane way).
Output: I can't think of any situation where I would prefer to receive void*
as opposed to something derived from a known base class.
Just to make it clear what I mean: I'm not specifically asking if there is a use-case for void*
, but if there is a case where void*
is the best or only available choice. Which has been perfectly answered by several people below.
void*
is at least necessary as the result of ::operator new
(also every operator new
...) and of malloc
and as the argument of the placement new
operator.
void*
can be thought as the common supertype of every pointer type. So it is not exactly meaning pointer to void
, but pointer to anything.
BTW, if you wanted to keep some data for several unrelated global variables, you might use some std::map<void*,int> score;
then, after having declared global int x;
and double y;
and std::string s;
do score[&x]=1;
and score[&y]=2;
and score[&z]=3;
memset
wants a void*
address (the most generic ones)
Also, POSIX systems have dlsym and its return type evidently should be void*
There are multiple reasons to use void*
, the 3 most common being:
- interacting with a C library using
void*
in its interface - type-erasure
- denoting un-typed memory
In reverse order, denoting un-typed memory with void*
(3) instead of char*
(or variants) helps preventing accidental pointer arithmetic; there are very few operations available on void*
so it usually require casting before being useful. And of course, much like with char*
there is no issue with aliasing.
Type-erasure (2) is still used in C++, in conjunction with templates or not:
- non-generic code helps reducing binary bloat, it's useful in cold paths even in generic code
- non-generic code is necessary for storage sometimes, even in generic container such as
std::function
And obviously, when the interface you deal with uses void*
(1), you have little choice.
Oh yes. Even in C++ sometimes we go with void *
rather than template<class T*>
because sometimes the extra code from the template expansion weighs too much.
Commonly I would use it as the actual implementation of the type, and the template type would inherit from it and wrap the casts.
Also, custom slab allocators (operator new implementations) must use void *
. This is one of the reasons why g++ added an extension of permitting pointer arithmatic on void *
as though it were of size 1.