Why is it impossible to have a reference to void? The only thing I found in the C++ Standard is this line, at 8.3.2.1
A declarator that specifies the type "reference to cv void" is ill-formed.
Why is it that way? Why can't I write a "generic" function that accept a void&
?
Just to be clear, I have no useful application in mind where using a reference-to-void could be better than using templates, but I'm just curious about the rationale for forbidding this construct.
To clarify a little, I understand that using a reference-to-void "as is" would be as meaningless as dereferencing a pointer-to-void. However, I could cast it to a reference-to-sometype in order to use it, couldn't I? In fact, I don't see why the following snippet can work...
void foo(void *data) { int *i = reinterpret_cast<int*>(data); // do something with i }
...while this one cannot:
void foo(void &data) { int &i = reinterpret_cast<int&>(data); // do something with i }
“References cannot be null, whereas pointers can; every reference refers to some object, although it may or may not be valid.”
The main use of references is acting as function formal parameters to support pass-by-reference. In an reference variable is passed into a function, the function works on the original copy (instead of a clone copy in pass-by-value).
Pass by reference (also called pass by address) means to pass the reference of an argument in the calling function to the corresponding formal parameter of the called function so that a copy of the address of the actual parameter is made in memory, i.e. the caller and the callee use the same variable for the parameter.
If you did have a reference to void, what would you do with it? It wouldn't be a number, or a character, or a pointer, or anything like that. Your hypothetical generic function couldn't perform any operation on it, except taking its address (and not its size).
"void" has two uses: to disclaim any knowledge of type (as in void *), and to specify nothing as opposed to something (void function return). In neither case is it possible to say anything about a void something except that it may have an address.
If you can't think of a way something can be useful, and I can't, that is at least evidence that something is useless, and that may well be at least part of the rationale here.
Ask your self first, how you would de-reference a void pointer?
void *p = /*something*/ ; cout << *p << endl;
The above code is meaningless, one of the reasons we have void is so we can say "I need to do some generic pointer work here, and I neither know nor care what I'm pointing to". By definition, the compiler doesn't know what a void * points to, therefore it can't dereference it. You can - by casting - but the compiler can't.
A reference to a void sufferes from the same problem, by definition the data pointed to doesn't have a type, therefore it can't be referenced in any meaningful way.
To reference it you - the programmer - need to cast it to another type, then you can have a typed reference to it.
Not sure if I explained this as well as I wanted to.
Ruben, any thoughts?
EDIT: To answer your edit.
Take the first function, where you pass void* data. data is a perfectly valid item, you can compute with it, or if you've some logging implemented, you can log it.
logger << data;
and you'll get the address data points to. If you try to dereference data, the compiler will give you an error (don't have C++ compiler handy at moment, so not sure of the actual error). e.g.
void* data = /* some assignment */; logger << *data; // compiler error.
Now, the compiler won't let you dereference a void* for any reason (it doesn't make sense), the same stands for a reference to void &data, except that because it's a reference it's implicitly dereferenced all the time. The compiler won't let you dereference a void* on one operation, it's not going to let you dereference it constantly.
void& data = /* some assignment *.; logger << data; // means same as logger << *data above
You can't do ANYTHING to data EXCEPT take it's address, and there's a perfectly good - and safe - method built into the languge to do that, i.e.
void* data;
Is this making any more sense?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With