int i = 1000;
void *p = &i;
int *x = static_cast<int*>(p);
int *y = reinterpret_cast<int*>(p);
which cast should be used to convert from void*
to int*
and why?
int i = 1000;
void *p = &i;
int *x = static_cast<int*>(p);
int *y = reinterpret_cast<int*>(p);
which cast should be used to convert from void*
to int*
and why?
static_cast
provided that you know (by design of your program) that the thing pointed to really is an int
.
static_cast is designed to reverse any implicit conversion. You converted to void*
implicitly, therefore you can (and should) convert back with static_cast
if you know that you really are just reversing an earlier conversion.
With that assumption, nothing is being reinterpreted - void
is an incomplete type, meaning that it has no values, so at no point are you interpreting either a stored int value "as void" or a stored "void value" as int. void*
is just an ugly way of saying, "I don't know the type, but I'm going to pass the pointer on to someone else who does".
reinterpret_cast
if you've omitted details that mean you might actually be reading memory using a type other than the type is was written with, and be aware that your code will have limited portability.
By the way, there are not very many good reasons for using a void*
pointer in this way in C++. C-style callback interfaces can often be replaced with either a template function (for anything that resembles the standard function qsort
) or a virtual interface (for anything that resembles a registered listener). If your C++ code is using some C API then of course you don't have much choice.
reinterpret_cast
if you're reinterpreting, which therefore will be implementation-specific. On some implementations, the alignment requirement for int
is 1, so that issue doesn't arise. On another implementation where the pointer could be mis-aligned, the same code would have exceeded its "limited portability". On still another implementation, you can't type-pun at all (except with char) because of strict aliasing rules. –
Marylnmarylou In current C++, you can't use reinterpret_cast
like in that code. For a conversion of void*
to int*
you can only use static_cast
(or the equivalent C-style cast).
For a conversion between different function type pointers or between different object type pointers you need to use reinterpret_cast
.
In C++0x, reinterpret_cast<int*>(p)
will be equivalent to static_cast<int*>(p)
. It's probably incorporated in one of the next WPs.
It's a misconception that reinterpret_cast<T*>(p)
would interpret the bits of p
as if they were representing a T*
. In that case it will read the value of p
using p
's type, and that value is then converted to a T*
. An actual type-pun that directly reads the bits of p
using the representation of type T*
only happens when you cast to a reference type, as in reinterpret_cast<T*&>(p)
.
As far as I know, all current compilers allow to reinterpret_cast
from void*
and behave equivalent to the corresponding static_cast
, even though it is not allowed in current C++03. The amount of code broken when it's rejected will be no fun, so there is no motivation for them to forbid it.
static_cast
and reinterpret_cast
conversion T* -> void* -> T* is guaranteed to yield the original value. And since this must hold for every pointer value, to foil it a perverse compiler would have to document some systematic needless change, like adding 1 when reinterpret_cast
from void*, and vice versa. Nobody would buy it. –
Doble void*
-> T*
or T*
-> void*
. –
Front static_cast
, §5.2.9/10. Secondly, 5.2.10/1 that you cite is in direct contradiction with §9.2/17. It's always amazed me that there's no formal Defect Report, but even if that inconsistency wasn't there, even if 5.2.10/1 was good, §5.2.10/7 + §5.2.9/10 says you're wrong on this. Sorry. Or, grin. :-) –
Doble void
is not an object type. Why is 5.2.10/1 in contradiction with 9.2/17? –
Front reinterpret_cast
as in the code above, until C++0x is adopted". Yes? –
Doble void*
would be possible :) Using reinterpret_cast<void*>(...)
is plain wrong in current C++ - it makes conceptually no sense either because reinterpret_cast is intended to be used to reinterpret something. With "void" one cannot reinterpret anything. Of course., I think my interpretation of this seems to be a bit retarded, though. –
Front reinterpret_cast
s. what it does is conceptually to "reinterpret" a pointer value, hence the name. doesn't matter what pointer points to. –
Doble When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used? gives some good details.
From the semantics of your problem, I'd go with reinterpret, because that's what you actually do.
static_cast
allows the same weird behavior if somebody mucks with the assignment to p
, e.g. assigning from a pointer to something smaller than an int
. I think the reason to use static_cast
is to communicate the intent of the conversion (i.e. that it's not supposed to reinterpret), but the cast itself doesn't actually prevent a reinterpret from happening, because void*
can be converted to and from any object pointer type. –
Marylnmarylou © 2022 - 2024 — McMap. All rights reserved.
void *
to start with. – Arouse