Different types of cast

C

Christof Warlich

Ravi said:
What is the difference between static cast and reinterpret cast?

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.
 
T

Tomislav Novak

With static_cast you may only cast within the same inheritance
hierarchy, i.e. it is more restrictive and thus somewhat safer.

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).
 
I

Ian Collins

Tomislav said:
static_cast also enables one to convert between types with implicit or
explicit conversion operators.


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.
 
J

Johannes Schaub (litb)

Ian said:
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?

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.
 
J

James Kanze

What is the difference between static cast and reinterpret 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.
 
J

James Kanze

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.)
 
J

James Kanze

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.
 
J

Johannes Schaub (litb)

James said:
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


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
 
J

Johannes Schaub (litb)

Johannes said:
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

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top