Cannot seem to cast void* to struct in c++ - c++

I have a very simple method with the following prototype:
void *station_0(void* p1);
I am calling it like this:
product_record r;
pthread_create(thread, NULL, station_0, (void *)&r);
Inside this method all I need to do is cast p1 to an already defined struct product_record, I am currently trying this inside of my method:
product_record p = (product_record)p1
but the compiler complains on that line(above) saying error: invalid conversion from 'void*' to 'int' [-fpermissive]
I don't think I understand this warning at all. Why cannot I simply cast a void* to my struct?

You need two steps - convert the void pointer to a product_record pointer and then de-reference that. This can be done in the line
product_record p = *(static_cast<product_record *>(p1));

Related

Compile error : cast void * failed in C/C++

I want to compile a project that I know works.
So I creat a Makefile to compile it, but when I make it I have this error:
invalid conversion from ‘void*’ to ‘LIMITOR_3DSL_Limitor_32f* {aka LIMITOR_3DSL_Limitor_32f_tag*}’ [-fpermissive]
*ppStatus = ippMalloc(sizeof(LIMITOR_3DSL_Limitor_32f));
^
It is really strange how could a void* can't be cast ?
Can the compiler be the problem ? I am using g++
Opposite to C in C++ you may not assign a pointer of type void * to a pointer of any other type because such an assignment is unsafe. You have to cast the pointer explicitly to the required type using a C or C++ form of casting.
For example
LIMITOR_3DSL_Limitor_32f *ppStatus = ( LIMITOR_3DSL_Limitor_32f * )ippMalloc( sizeof(LIMITOR_3DSL_Limitor_32f ) );
or
LIMITOR_3DSL_Limitor_32f *ppStatus = static_cast<LIMITOR_3DSL_Limitor_32f*>( ippMalloc(sizeof(LIMITOR_3DSL_Limitor_32f ) ) );
LIMITOR_3DSL_Limitor_32f* ppStatus = (LIMITOR_3DSL_Limitor_32f*)ippMalloc(sizeof(LIMITOR_3DSL_Limitor_32f));
In C/C++ we should cast type explicitly. ippMalloc will return a void * pointer, so we should cast it from void * to LIMITOR_3DSL_Limitor_32f*

In C++, I'm getting a message "error: 'void*' is not a pointer-to-object type"

Here's my code:
#include <iostream>
using namespace std;
int main()
{
void *x;
int arr[10];
x = arr;
*x = 23; //This is where I get the error
}
As you can see, the code is very simple. It just creates a void pointer x which points to the memory address of the array 'arr' and puts the integer 23 into that memory address. But when I compile it, I get the error message "'void*' is not a pointer-to-object type". When I use an 'int' pointer instead of a void pointer and then compile it, I don't get any errors or warnings. I wanna know why I get this error.
Thank you.
As the compiler message says, void* is not a pointer to object type. What this means is that you cannot do anything with void*, besides explicitly converting it back to another pointer type. A void* represents an address, but it doesn’t specify the type of things it points to, and at a consequence you cannot operate on it.
The compiler needs the type of the variable to to dereference the pointer.
only example no malloc:
*int myPtnr = 0x12345;
When you write
*myPtr = NUMBER:
The compiler looks at the type and say .. okay here we have a int ... the Information i need are in the next 4 bytes starting with the adress of the pointer.
Thats the reason why you have to tell the compiler the type. When you use void the compiler dont know how much bytes he has to use for dereference.
you cant derefrence void*, and that is what the coder is doing.
*x = 23; // this cant be done with void*
instead :
x = &arr[index] ; // this is correct

usage of void** in c++ program

I have to use void** in a program. I am writing the following code. please guide me where I am wrong.
struct kdnode
{
kdnode* lch;
int k;
void **dataptr;
kdnode* rch;
};
then I am assigning
kdnode rt;
rt.dataptr=new void*[k];
rt.dataptr[0]=new int;
there was also this dereferencing involved:
*(rt->dataptr[0])=n; //n is an initialized integer value.
basically I want to assign the elements of the array of void pointers to pointers of different datatypes. As the compiler is throwing error :
void* is not a pointer-to object type
Please guide me what to do.
I can reproduce this error only if I add something like
*rt.dataptr[0] = 1;
With the addition, g++ complains:
main.cpp:13:14: error: ‘void*’ is not a pointer-to-object type
*rt.dataptr[0] = 1;
You can't dereference a void *. Cast it back to the original type (int * in this case) if you want to dereference it.

static_cast void* char* vs static_cast void** char**

If I do the following all is ok:
char* cp = "abc";
void* vp = NULL;
vp = static_cast<void*>(cp);//ok
cp = static_cast<char*>(vp);//ok
But the following is not:
char** cpp = &cp;
void** vpp = NULL;
vpp = static_cast<void**>(cpp);//error C2440: 'static_cast':
//cannot convert from 'char **' to 'void **'
cpp = static_cast<char**>(vpp);//error C2440: 'static_cast':
//cannot convert from 'void **' to 'char **'
Please can someone explain to me why the second examples are not allowed. Please don't quote the C++ standard as your whole answer, because I've already seen answers that quote it, and I don't understand what they meant. I want to understand why the second examples don't work (ie. if you could give an example where it would be dangerous that would be a great help). Because I don't get it. To me, both examples are casting pointers. Why does an additional level of indirection make any difference?
A void * pointer can point at "anything", and it is valid to convert all pointers to a void *, and it is valid to convert all pointers from void * to some other type.
However, a void ** is a pointer that points to a void * value. And a char ** is a pointer that points to char * value. These types don't point to the types that are convertible from one another. You can, if you NEED to do this, use void **vpp = reinterpret_cast<void **>(cpp);, but it's "not safe" (you are basically telling the compiler "Look, I know what I'm doing here, so just do it", which may not do what you actually expected...)
The restriction is to avoid breaking the type system. The first conversion is fine:
type *p = ...;
void *vp = p;
While you are giving away the type, you cannot inflict too much damage to the original value without since there is little to be done with a void object and all changes to vp are local to the pointer and cannot affect p.
If the second case was allowed:
type **p = ...;
void **vp = p;
Then perfectly looking and correct code could break your application. For example:
int *parray[10];
int **p = parray;
void **vp = p;
*vp = new double(); // now parray[0] is a pointer to a double object,
// not a pointer to an int!!!
The type system has been subverted.
That is, the problem is that in the second case there are operations that can be applied to the destination pointer that can modify the original object and cause bugs. Similar examples can be found with const other cases (you can convert int* to const int*, but you cannot convert int** to const int**...).

C++ typecast error [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
void pointers: difference between C and C++
Hi I have the following function:
void task2(int a)
{
printf(" Task 2 running..\n");
sleep(2);
printf(" Task 2 exiting..\n");
}
thpool_add_work(threadpool, (void*)task2, (void*)a);
int thpool_add_work(thpool_t* tp_p, void *(*function_p)(void*), void* arg_p)
{
// some code here
}
The above code works well with C, but does not compile in C++. I'm getting the following error:
error: invalid conversion from ‘void*’ to ‘void* (*)(void*)’
error: initializing argument 2 of ‘int thpool_add_work(thpool_t*, void* (*)(void*), void*)’
I'm not able to figure out the reason for this error. Any idea why this error crops up when I change the file extension to CPP and compile?
You have to change the signature of task2 to match the type of the thpool_add_work argument:
void* task2(void* a)
The call which creates the thread would become
thpool_add_work(threadpool, task2, &a);
assuming that a is int.
If you need to use the argument of task2, you could do following:
int ia = *(int*)a;
Update to answer the OP comment
thpool_add_work expects a function with void* argument for a reason. In such a way, you can pass any kind of parameter into the thread function, albeit in a type-unsafe way.
You pass the address of the parameter converted to void* as the 3rd argument of thpool_add_work. Afterwards, you cast a pointer to void back to the pointer to your expected parameter type and dereference it to get the value of the parameter. I gave the example for int a above, now how it would look for a float:
void* test3(void* a)
{
float fa = *(float*)a;
.....
return NULL;
}
Try this
thpool_add_work(threadpool, (void* (*)(void*))task2, (void*)a);
C converts void* to any type automatically, C++ does not.
You could improve the code with a typedef
typedef void* (*worker_func_t)(void*);
thpool_add_work(threadpool, (worker_func_t)task2, (void*)a);
int thpool_add_work(thpool_t* tp_p, worker_func_t function_p, void* arg_p)
{
// some code here
}