1

I'm looking through some c++ wrapper code that provides a c api, and I'm finding lots of reinterpret_cast where a static_cast would suffice, e.g.:

struct cpp_object{ void foo(){ /* do something */ } };

/* begin: c api */
typedef void c_object;

void foo(c_object *o)
{
    // why this:
    reinterpret_cast<cpp_object *>(o)->foo();
    // instead of just:
    static_cast<cpp_object *>(o)->foo();
}
/* end: c api */

Generally I use reinterpret_cast in rare situations, mostly related to forced bit coersion of buffer contents to a type of know layout and size, known to lie inside buffer contents.

So I ask whether that practice makes sense or sticking to static_cast would be a better one.

oblitum
  • 11,380
  • 6
  • 54
  • 120

2 Answers2

1

In this case the reinterpret_cast is equivalent to a static_cast to cv void* and then another static_cast to the target pointer type. This is an addition to C++11 I believe and wasn't present in C++03, where you had to write the two static_casts to get portable behaviour.

Simple
  • 13,992
  • 2
  • 47
  • 47
  • but the void pointer parameters being accepted doesn't have any cv qualification, so `const_cast` is never necessary and `static_cast` works. – oblitum Oct 07 '13 at 19:34
  • @chico `static_cast` can add cv-qualifiers it just can't remove them. `cv void*` in my example is to indicate that it `static_cast`s to a `void*` where the `void` has the same cv-qualifications as the source pointer. – Simple Oct 07 '13 at 19:37
  • yes, I know that, probably you meant then a `const_cast` after the first `static_cast` but in any case... the parameters have no cv qualification, so it's irrelevant. – oblitum Oct 07 '13 at 19:39
  • @chico You've lost me. `reinterpret_cast(o)` is equivalent to `static_cast(static_cast(o))`. There is no `const_cast` involved in a `reinterpret_cast`. – Simple Oct 07 '13 at 19:42
  • ok, but, as I'm trying to say. `o` is already just `void *` isn't? there's no cv requalification in that cast. That's what I was trying to say, but, anyway, now I ask, that first cast seems unecessary, unless it's turned so because I'm dealing with pointers for typedefs to `void`? – oblitum Oct 07 '13 at 19:45
  • @chico It will still convert the `void*` that is `o` into another `void*` and then do the final cast. This doesn't matter though because it has no runtime overhead. I actually didn't notice `c_object` was an alias for `void`, in which case I would prefer just using `static_cast` but this answer still applies. – Simple Oct 07 '13 at 19:47
  • ok, I'm no interested in the runtime aspect, my only concern now, with your reasoning, is whether this first cast you made is not mandatory or mandatory good practice, if it's not, then it can be removed, and a single `static_cast` already should do the job, no need for `reinterpret_cast` backed by that reasoning. – oblitum Oct 07 '13 at 19:49
  • C++03 already allowed `static_cast` to convert from a `void*` to an object pointer type, see [expr.static.cast]/10. – dyp Oct 07 '13 at 19:59
  • ah, ok, you've already answered that in the previous comment... – oblitum Oct 07 '13 at 20:31
0

I think in this case you have to use reinterpret_cast because c_object is of type void, so o is of void *. The compiler can not guess that o is. It has to be a run-time cast.

CS Pei
  • 10,869
  • 1
  • 27
  • 46