Here's a summary of the different things that have been said, and that I've thought of.
Two main reasons why reference-to-void are disallowed
1 They would have been totally useless.
Indeed, if we look back at the times of C, void pointers had two purposes:
- Memory management (e.g. malloc)
- Genericity (writing functions that can accept any type of arguments)
When C++ came out, templates became the best solution to implement genericity. However, custom memory management still had to be possible, and interoperability between C++ and C was a major concern, so void* was kept. An hypothetical void reference would be of no help with memory management, and genericity is already covered, so basically it would have almost no use (except for the guarantee of non-nullness described below).
2 You wouldn't be able to do anything with it
When using a void pointer, you're not allowed to dereference it; transposed to the case of references, that means you can't use the (always hypothetical) void reference. So
void *data = // something
// using *data and data-> is forbidden
void &data = // something
// using data is forbidden
However, we could think of a use case where the reference wouldn't have to be "dereferenced" (this phrase is awfully incorrect, but you get my point), but where we would only take its address . Let's assume I have the following function:
void foo(void *dataptr)
{
assert(dataptr != NULL); // or != 0
// do something with dataptr
}
To avoid this annoying assert, I could write the function this way:
void foo(void &dataref)
{
void *data = &dataref;
// do something with data
}
However, for this to work, &dataref
needs to be equivalent to dataptr
, which is not the case: &dataref
is equivalent to &*dataptr
!
Therefore, even taking the address implies a dereferencing, at least conceptually (behind the scenes, the first equivalence is probably true, but at the semantic level it is not). Consequently, there is absolutely no usage we can make of data, so void references are an aberration.