Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting a pointer by reference

I came across something I don't understand well. Let's suppose I want to pass a character pointer to a function that takes a reference to a void pointer.

void doStuff(void*& buffer)
{
  // do something
}

I would usually do something like this :

int main()
{
  unsigned char* buffer = 0;
  void* b = reinterpret_cast<void *>(buffer);
  doStuff(b);
  return 0;
}

Why it is not possible to directly pass the reinterpret_cast to the function?

int main()
{
  unsigned char* buffer = 0
  // This generate a compilation error.
  doStuff(reinterpret_cast<void *>(buffer));
  // This would be fine.
  doStuff(reinterpret_cast<void *&>(buffer));
  return 0;
}

There must be a good reason behind this behavior but I don't see it.


1 Answers

In the first example, you're actually passing the pointer variable b. So it works.

In the second example, the first reinterpret_cast returns a pointer (by value), which doesn't match the reference the function should get, while the second returns said reference.

As an example to show you how references work, look at these two functions,

void doSomething( unsigned char *ptr );
void doSomethingRef( unsigned char *&ptr );

Say we have this pointer,

unsigned char *a;

Both functions are called the same way,

doSomething( a ); // Passing pointer a by value
doSomethingRef( a );// Passing pointer a by reference

Though it may look like you're passing it by value, but the function takes a reference so it will be passed as a reference.

A reference is similar to a pointer but it has to be initialized with a left value and can't be null.


Having said that, there are much better alternatives to using void* and especially void*&. void* makes code harder to read and easier to shoot yourself in the foot (if anything by making yourself use these strange casts).

As I said in the comments, you could use a template and not bother with void casting.

template< class T > void doStuff( T *&buffer ) {
    ...
}

Or,

template< class T > T* doStuff( T* buffer ) {
    ...
}

EDIT: On a side note, your second example is missing a semicolon,

unsigned char* buffer = 0; // Right here
like image 130
aslg Avatar answered Aug 30 '26 00:08

aslg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!