I am working on RTOS project and I'm trying to pass struct type typecasted to void pointer to thread function and derefernce that void pointer using typecast to same struct type. I was getting error when trying to do it this way (eUartDriver_t*) *args
. Then found on the internet to use *(eUartDriver_t*) args
, but it didn't explained the difference and why does it work
CodePudding user response:
Presumably args
is declared to be a void *
. The expression *args
means “the thing args
points to,” so *args
would be a void
, but void
is not a usable type. So *args
is bad code, and the compiler complains.
(eUartDriver_t *) args
says “Convert the value of args
to eUartDriver_t *
”. That type is a pointer to an eUartDriver_t
. The result of this conversion is a pointer to an eUartDriver_t
, so applying *
, as in * (eUartDriver_t *) args
, refers to a eUartDriver_t
, which is a usable type.
CodePudding user response:
@UnholySheep
Order of operations matters a lot. *args dereferences the pointer, so casting that to another pointer type afterwards may not be possible (since the result is possibly not a pointer type)
#include <stdio.h>
int main()
{
//Consider integer:
int x;
//And pointer to it.
int *p= &x;
//These expressions
p; &x;
//are of type int*, which means the dereferencing operator can be used on these.
//This is legal:
*p; *(&x); p[0];
//Pointer casting <==> reinterpretation of pointer (address)
//These expressions are almost the same (have the same values and storage space)
(int*)p; (char*)p; p; (void*)p;
/*The only difference is in dereferencing or artmetics, which must happen
AFTER the pointer is known as (new) type pointer.
So once you've got this expression:*/
(char*)p;
//or new variable:
char *newP= (char*)p;
//or macro:
#define newP (char*)p
//THAN you can do derefrencing with proper use of operators *ptr or ptr[offset]
*newP; *((char*)p); newP[0]; ((char*)p)[0];
}