How to cast a pointer in C++
Solution 1
(void*) is not an lvalue, it is kind of a casting operator, you need to have the ampersand to the immediate left of the variable (lvalue). This should be right:
foo(((void**)&IntPtr));
Solution 2
void foo(void **Pointer);
int main ()
{
int *IntPtr;
foo((void**)&IntPtr);
}
Solution 3
When you do
(void*)IntPtr
you create a temporary variable, which is only an rvalue, and so can't be dereferenced.
What you need to do is:
int main()
{
int* IntPtr;
void* VoidPtr = (void*)IntPtr;
foo(&VoidPtr);
}
or equivalent
Solution 4
More C++ style:
foo( reinterpret_cast< void** >( IntPtr ) );
But remember, according to Standard such a cast is implementation specific. Standard gives no guarantees about behavior of such cast.
Solution 5
As others point out, you have the order of the cast and the &
wrong. But why do you use void**
at all? That means that you accept a pointer to a void pointer. But that's not at all what you want. Just make the parameter a void*
, and it will accept any pointer to some object:
void foo(void*);
int main () {
int *IntPtr;
foo(&IntPtr);
assert(IntPtr == NULL);
}
That's what void*
is for. Later, cast it back using static_cast
. That's a quite restrictive cast, that doesn't allow dangerous variants, unlike the C style cast (type):
void foo(void* p) {
int** pint = static_cast<int**>(p);
*pint = NULL;
}
If the function takes pointers to void*
, then that function can't accept pointers to int*
. But if the function accepts either or, then the function should accept void*
, and you should cast to the proper type inside the function. Maybe paste what you really want to do, we can help you better then. C++ has some good tools available, including templates and overloading, both of which sound helpful in this case.
jackhab
Updated on January 22, 2020Comments
-
jackhab over 4 years
void foo(void **Pointer); int main () { int *IntPtr; foo(&((void*)IntPtr)); }
Why do I get an error?
error: lvalue required as unary ‘&’ operand
Thanks
-
mmx over 15 yearscrashmstr: It's required to explicitly cast to void** in C++. If it was a void* you wouldn't need a cast, however it's not void*, it's void**.
-
Geekoder over 15 yearsHowever, it is interesting to note that every modification made on Pointer in foo will only affect VoidPtr and not IntPtr (since I guess it was the aim of the OP).
-
crashmstr over 15 yearsAh, sorry! I have not had to work with void pointers in a while :)
-
Darron over 15 yearsThat should be "foo( reinterpret_cast< void** >( &IntPtr ) )"
-
Rob K over 15 yearsYeah, this solution isn't right. You're only copying the (uninitialized) value of IntPtr to VoidPtr in the assignment. You're not making VoidPtr point to IntPtr. You want to do void* VoidPtr = (void*)(&IntPtr);
-
Martin York over 15 yearsThat will not work as expected. You need to add the last step of copying the conetent back from VoidPtr into IntPtr
-
jackhab over 15 yearsI use void** because I have an array of void pointers and the function returns one of the pointers inside void** argument.
-
Johannes Schaub - litb over 15 yearswell, casting to void** is like casting to int** in that regard. void** is nothing special. the questioner should use void*
-
Johannes Schaub - litb about 15 yearsyou have a int pointer in your question not an array of void pointers, though.
-
Tobias Wärre almost 13 years@Johannes, except that foo takes a void** and not a void* which is strictly speaking a type mismatch. And also, it helps to understand the flow, there is little gain of speaking of a pointer-to-a-pointer as a pointer when readability comes into concern.