Why does it require double casting

Guys, the code below compiles fine:
&mut errhp_ctl as *mut *mut OCIError as *mut *mut c_void
but this code errors:
&mut errhp_ctl as *mut *mut c_void

errhp is of type *mut OCIError.
What I don't understand here is why do I have to cast it twice, not just straight to the target type that is c_void?

The two casts are distinct operations. The first is a coercion of a mutable reference to a pointer and the second is a cast from a pointer of type T to a pointer of type U. If we pretend we had different functions for each cast instead of a type-cast operator in as, I think of this as pointer_cast::<*mut c_void>(mut_to_pointer::<*mut OCIError>(&mut errhp_ctl)). If you leave out the call to mut_to_pointer, the input to pointer_cast will be wrong, thus the error.

OK, so basically, first we need to make ptr from ref and only then that ptr to other ptr. Makes sense. Thanks.

the first coercion can be replaced with the raw borrow operator:

&raw mut errhp_ctl as *mut *mut c_void

Hey, I've tried to check this, but I'm getting error that raw is not found in this scope? Any idea as to why?
&mut errhp_ctl as *mut *mut c_void?

what's your compiler's version? the &raw syntax was stablized back in 1.82.

OK, that must be it. Thanks.
So as I do not have a way to check it, basically having &raw makes it possible to get rid of the first casting/coersion, i.e. as *mut *mu _
Is that correct?

when you use the regular borrow operator &mut errhp_ctl, you get a reference to errhp_ctl, which needs to be coerced to the raw pointer with the as operator first, and then be casted to the target pointer type.

when you use raw borrow operator &raw mut errhp_ctl, you get a raw pointer to errhp_ctl directly, so you only need to cast it once.

1 Like