How to cast a pointer without assignment in C?

1k Views Asked by At

I have pointers of type void *, but I know that they are in fact pointing to a struct. When I assign them casted to another pointer and use it, then everything works fine, but I'm not able to use the casted void pointer directly.

Here is an example:

typedef struct {
    int x1;
    int x2;
} TwoX;

main()
{
   void * vp;
   TwoX xx, *np, *nvp;
   xx.x1 = 1;
   xx.x2 = 2;

   vp = (void *)&xx;
   np = &xx;
   nvp = (TwoX *)vp;
   printf ("test normal pointer: %d %d\n", np->x1, np->x2);
   printf ("test recast void pointer: %d %d\n", nvp->x1, nvp->x2);
   //printf ("test void pointer: %d %d\n", (TwoX *)(vp)->x1, (TwoX *)(vp)->x2); // this line doesn't compile

}

The last printf line doesn't compile and I get the following error and warning twice (one for each casting):

warning: dereferencing void * pointer [enabled by default]
error: request for member x1 in something not a structure or union

Without that line everything works and the output is:

test normal pointer: 1 2
test recast void pointer: 1 2

How can I cast a void * pointer without assigning it to a new variable?

2

There are 2 best solutions below

0
On BEST ANSWER

In your code, change

printf ("test void pointer: %d %d\n", (TwoX *)(vp)->x1, (TwoX *)(vp)->x2);

to

printf ("test void pointer: %d %d\n", ((TwoX *)(vp))->x1, ((TwoX *)(vp))->x2);
                                      ^            ^      ^            ^
                                      |            |      |            |

Without the extra pair of parenthesis, dererence operator -> has higher precedence over typecasting, so the (Two *) is not being effective before dereferencing.

As per the logic, you cannot dereference a void type pointer. That's why the warning. Next, when you are requesting to access some member variable of a structure pointer, the pointer is expected to be of type of that structure, which is not happenning (because it is still void type), so the error.

You can check the operator precedence here.

0
On

I think this is just an order of operations issue. Try ((TwoX*)vp)->x1. Notice that the cast and pointer are grouped together with parentheses.