With static_cast you may only cast within the same inheritance
hierarchy, i.e. it is more restrictive and thus somewhat safer.
dynamic_cast is similar, adding run-time checking and making the cast
really safe.
reinterpret_cast allows any cast.
static_cast also enables one to convert between types with implicit or
explicit conversion operators.
> dynamic_cast is similar, adding run-time checking and making the cast
> really safe.
>
> reinterpret_cast allows any cast.
Of course, it works for pointer types only (just to clarify further).
--
T.
No, it works for any type with the same size. But it can't be used to
cast away const or volatile.
--
Ian Collins
No, you are wrong. reinterpret_cast only allows very limited casts, like
every other c++ cast does. It does, in particular allow not to do
reinterpret_cast<unsigned char>('a'); // same size, eh?
And it does not allow casting to void* from another pointer, or from void*
to another pointer. It's just what its name is: It *reinterprets* pointer
representations to integers, and object/member pointers among themselves.
It also allows reinrerpreting arbitrary objects (disregarding their size) by
using references: "reinterpret_cast<unsigned char&>(some_int)" is perfectly
valid.
It's not as simple as that (you shouldn't replace a dynamic_cast by a
static_cast and expect it to work if you're using virtual inheritance).
In particular, see FAQ 25.13 (brief though it is).
I actually asked about this a few years back and got a good answer from
Janusz Szpilewski which I'll reproduce here:
"Internal implementation of classes having virtual base classes is quite
complex. Usually such a virtual base is referenced by a pointer and it
may happen that such a base part is not even contiguous in the memory
with the derived object part.
Hence to make a correct cast to a class with virtual base classes some
runtime information about the actual (dynamic) type of the object being
casted may be required. Only dynamic_cast offers a possibility of
consulting the dynamic object type."
In my case I was asking for (what I would now describe as dubious)
performance-related reasons - in which case the key thing to bear in
mind is that you should be avoiding casting as much as possible anyway,
so there shouldn't be enough casting happening for performance to be an
issue in the first place.
Regards,
Stu
> reinterpret_cast allows any cast.
The semantics. They do completely different things.
A static_cast requests a true conversion, int to double, for
example. When pointers are involved, it navigates up and down
the hierarchy. A reinterpret_cast requests the compiler to
interpret a value "as if" it had in fact some other type, to the
best of its ability. In a very real sense, it doesn't do any
conversion at all. It's use is pretty much limited to very low
level software, involving the underlying memory, and not the
objects themselves.
--
James Kanze
> > static_cast also enables one to convert between types with
> > implicit or explicit conversion operators.
> >> dynamic_cast is similar, adding run-time checking and
> >> making the cast really safe.
> >> reinterpret_cast allows any cast.
> > Of course, it works for pointer types only (just to clarify further).
> No, it works for any type with the same size.
Size has nothing to do with it. For a reinterpret_cast to be
legal, one of its operands must be a pointer or a reference.
A pointer can also be cast to and from an integral type (with
some restrictions concerning whether it fits in such cases).
But as I said in my reponse to the OP, the important difference
is semantics: a reinterpret_cast has distinctly different
semantics from a static_cast, even in the cases where both are
legal.
> But it can't be used to cast away const or volatile.
That's true for all of the casts mentionned. (Note, however,
that since the result of a conversion is only an lvalue if the
conversion is to a reference, top level const or volatile is
irrelevant and ignored.)
--
James Kanze
> >> Of course, it works for pointer types only (just to clarify further).
> > No, it works for any type with the same size. But it can't
> > be used to cast away const or volatile.
> No, you are wrong. reinterpret_cast only allows very limited
> casts, like every other c++ cast does. It does, in particular
> allow not to do
> reinterpret_cast<unsigned char>('a'); // same size, eh?
That's true.
> And it does not allow casting to void* from another pointer,
> or from void* to another pointer.
Yes it does. It allows converting any object pointer type to
any other object pointer type (and in this context, void* is
considered an object type). Even if the two pointers have
different sizes, e.g. void* and int* on some machines. It also
allows converting any pointer to function type to any other
pointer to function type; it does not, however, allow converting
pointer to object (including void*) to or from pointer to
function, even if the two have the same size, as if often the
case (and is required by Posix, and I think at least indirectly
by Windows). Note that quite a few Unix compilers err here, and
accept the cast.
> It's just what its name is: It *reinterprets* pointer
> representations to integers, and object/member pointers among
> themselves.
> It also allows reinrerpreting arbitrary objects (disregarding
> their size) by using references: "reinterpret_cast<unsigned
> char&>(some_int)" is perfectly valid.
Yes, although in most cases, it's probably preferable to pass
through a pointer, e.g. reinterpret_cast< unsigned char* >(
&some_int ).
Here, size can affect the usability of the results:
reinterpret_cast< int& >( some_unsigned_char ) might be legal,
but using the results of the reinterpret_cast is undefined
behavior.
--
James Kanze
> On Dec 24, 4:39 pm, "Johannes Schaub (litb)" <schaub-johan...@web.de>
> wrote:
>> Ian Collins wrote:
>> > Tomislav Novak wrote:
>> >> On 2009-12-24, Christof Warlich <cwarl...@gmx.de> wrote:
> [...]
>> >>> reinterpret_cast allows any cast.
>
>> >> Of course, it works for pointer types only (just to clarify further).
>
>> > No, it works for any type with the same size. But it can't
>> > be used to cast away const or volatile.
>
>> No, you are wrong. reinterpret_cast only allows very limited
>> And it does not allow casting to void* from another pointer,
>> or from void* to another pointer.
>
> Yes it does. It allows converting any object pointer type to
> any other object pointer type (and in this context, void* is
> considered an object type). Even if the two pointers have
> different sizes, e.g. void* and int* on some machines. It also
> allows converting any pointer to function type to any other
> pointer to function type; it does not, however, allow converting
> pointer to object (including void*) to or from pointer to
> function, even if the two have the same size, as if often the
> case (and is required by Posix, and I think at least indirectly
> by Windows). Note that quite a few Unix compilers err here, and
> accept the cast.
>
void* is not a "pointer to an object" - it's a "pointer to void". The
reinterpret_cast paragraph precisely only allows casting for two pointers if
both are pointers to object types. There is no mentioning of void types.
The pointer type category is defined at 3.9.2/1 as "pointers to void or
objects or functions (including static members of classes) of a given type",
they are three different categories.
There was some work under way to define the word "object pointer" and use it
in reinterpret_cast to include "pointer to void" - but this work has not yet
been included into any draft. See http://www.open-
std.org/jtc1/sc22/wg21/docs/cwg_active.html#573
>> It's just what its name is: It *reinterprets* hointer
>> representations to integers, and object/member pointers among
>> themselves.
>
>> It also allows reinrerpreting arbitrary objects (disregarding
>> their size) by using references: "reinterpret_cast<unsigned
>> char&>(some_int)" is perfectly valid.
>
> Yes, although in most cases, it's probably preferable to pass
> through a pointer, e.g. reinterpret_cast< unsigned char* >(
> &some_int ).
>
> Here, size can affect the usability of the results:
> reinterpret_cast< int& >( some_unsigned_char ) might be legal,
> but using the results of the reinterpret_cast is undefined
> behavior.
>
Agreed - as in the spirit of 3.10/15
Actually the current draft n3000 uses reinterpret_cast<void*>(P) in the
specification of safely-derived pointers at 3.7.3.4/3 - so i think it's
actually needed to include the above "object pointer" fix, or something
similar, into the final C++0x Standard.