Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   reinterpret_cast<>() v. static_cast<>() (http://www.velocityreviews.com/forums/t280611-reinterpret_cast-v-static_cast.html)

Scott Brady Drummonds 01-13-2004 09:53 PM

reinterpret_cast<>() v. static_cast<>()
 
Hi, everyone,

I've checked a couple of on-line resources and am unable to determine how
reinterpret_cast<> is different from static_cast<>. They both seem to
perform a compile-time casting of one type to another. However, I'm certain
that there is something else that is happening.

Can someone explain the difference or recommend an online site that can
explain it to me?

Thanks,
Scott

--
Remove ".nospam" from the user ID in my e-mail to reply via e-mail.



David Harmon 01-13-2004 10:16 PM

Re: reinterpret_cast<>() v. static_cast<>()
 
On Tue, 13 Jan 2004 13:53:48 -0800 in comp.lang.c++, "Scott Brady
Drummonds" <scott.b.drummonds.nospam@intel.com> was alleged to have
written:
>Hi, everyone,
>
>I've checked a couple of on-line resources and am unable to determine how
>reinterpret_cast<> is different from static_cast<>. They both seem to
>perform a compile-time casting of one type to another. However, I'm certain
>that there is something else that is happening.


static_cast<> uses sensible, well-defined conversions. For example, the
integer 10 would be converted to the double 10.0.

reinterpret_cast<> just looks at the bits in memory in as if they were
the encoding as a different type. For example, the integer 10 would
look like some number who-knows-what as a double.



Ron Natalie 01-13-2004 10:17 PM

Re: reinterpret_cast<>() v. static_cast<>()
 

"Scott Brady Drummonds" <scott.b.drummonds.nospam@intel.com> wrote in message news:bu1pdd$1po$1@news01.intel.com...
> Hi, everyone,
>
> I've checked a couple of on-line resources and am unable to determine how
> reinterpret_cast<> is different from static_cast<>. They both seem to
> perform a compile-time casting of one type to another. However, I'm certain
> that there is something else that is happening.


There are two major differences:
1. static_cast won't convert certain types (you'll get a compile error).
2. when both will perform the conversion, the nature of the conversion is different.

Static_cast has two uses. First it will force a conversion that could have happened implicitly.
For example:
double value = 1.45;
double remainder = value - static_cast<int>(value);

Here we force a conversion that could be done implicitly with an extra temporary variable.
The other use, is to reverse a defined conversion. If there is a valid forward conversion,
in most cases you can reverse it with a static cast.

struct Base {
};
struct Derived : Base {
};

Derived d;
Base* bp = &d; // implicit conversion.
Derived* dp = static_cast<Derived*>(bp); // invert valid conversion.

A reinterpret cast pretty much says, treat these bits as another type. Its results are implementation
specific in most cases. You can do things like:
char* foo = ...

unsigned char* foo = reinterpret_cast<unsigned char*>(foo); // force type change!

Needless to say you should think twice in general before doing this. The compiler will
refuse to do the static_cast of the above types because they are unrelated (no conversion
defined in either direction).

Now here's a case where they both casts will do something different (in many circumstances):

struct BaseA {
char a;
};
struct BaseB {
char b;
};
struct Derived : BaseA, BaseB {
};

Derived d;
BaseB* bp = static_cast<BaseB*>(&d); // valid: bp now points to BaseB subobject of d
BaseB* rp = reinterpret_cast<BaseB*>(&d); // probably not valid, could result in rp pointing at
// the BaseA memory in d but with the BaseB* type.



AngleWyrm 01-14-2004 12:06 AM

Re: reinterpret_cast<>() v. static_cast<>()
 

"Scott Brady Drummonds" <scott.b.drummonds.nospam@intel.com> wrote in
message news:bu1pdd$1po$1@news01.intel.com...
> Can someone explain the difference or recommend an online site that can
> explain it to me?


static_cast<> is for related casts; (float->int, int->enum, etc).
reinterpret_cast<> is for totally unrelated type conversions (which
shouldn't usually be done). For example:

// Converting a hex number to a device port
IO_device* myDevicePort = reinterpret_cast<IO_device*>(0XFF00) // device at
0xFF00



Scott Brady Drummonds 01-14-2004 07:04 PM

Re: reinterpret_cast<>() v. static_cast<>()
 

"Ron Natalie" <ron@sensor.com> wrote in message
news:40046e6f$0$62140$9a6e19ea@news.newshosting.co m...
>
> "Scott Brady Drummonds" <scott.b.drummonds.nospam@intel.com> wrote in

message news:bu1pdd$1po$1@news01.intel.com...
> > Hi, everyone,
> >
> > I've checked a couple of on-line resources and am unable to determine

how
> > reinterpret_cast<> is different from static_cast<>.

....
> There are two major differences:
> 1. static_cast won't convert certain types (you'll get a compile

error).
> 2. when both will perform the conversion, the nature of the

conversion is different.
....

Thank you so much, Ron, for the detailed description!

Scott



forums_mp 01-15-2004 02:42 AM

Re: reinterpret_cast<>() v. static_cast<>()
 
"Scott Brady Drummonds" <scott.b.drummonds.nospam@intel.com> wrote in message news:<bu1pdd$1po$1@news01.intel.com>...
> Hi, everyone,
>
> I've checked a couple of on-line resources and am unable to determine how
> reinterpret_cast<> is different from static_cast<>. They both seem to
> perform a compile-time casting of one type to another. However, I'm certain
> that there is something else that is happening.
>
> Can someone explain the difference or recommend an online site that can
> explain it to me?
>
> Thanks,
> Scott


Interestingly enough I just went through the process of laying some
ground rules on the use of the C++ casts.
A synopsis of what I was able to deduce - of course the experts will
correct me if I'm mistaken

---------
reinterpret_cast is ONLY for pointers, of the same constness. You can
cast a char* to an unsigned char* or any other * with
reinterpret_cast, but you can't cast off constness with reinterpret
cast.

const_cast is to cast off constness. If you have a const char* and
ABSOLUTELY MUST get rid of its constness and KNOW FOR A FACT that that
operation is safe AND you can't just make a new copy of the buffer ...
then const_cast is your tool.

static_cast is for casting a base class to a derived class. No
runtime type checking is performed so this seems/is inherently
dangerous, but sometimes if you are stuck with a bad design ...
unavoidable. You can also cast an int to an enum using static cast,
as well as a few other things.

dynamic_cast is a "safe" way to cast a base class to a derived class,
but it requires you to include type information in your build. if at
runtime, if the cast can't be performed, then the cast returns 0,
otherwise the cast succeeds and you continue your program.

---------

Along the same lines I have a question.
Notwithstanding the C++ casts are limited in scope which in my view
implies (no proof though) that they are safer than the C variant,
whats the 'real' gain over the C cast? A question that seems to crop
up with no reasonable answer on my part. I suspect in the grand
scheme of things casting it's low level bit twiddling on both parts
(C/C++)

----------

Cy Edmunds 01-15-2004 03:36 AM

Re: reinterpret_cast<>() v. static_cast<>()
 
[snip]

> Along the same lines I have a question.
> Notwithstanding the C++ casts are limited in scope which in my view
> implies (no proof though) that they are safer than the C variant,
> whats the 'real' gain over the C cast? A question that seems to crop
> up with no reasonable answer on my part. I suspect in the grand
> scheme of things casting it's low level bit twiddling on both parts
> (C/C++)
>
> ----------


C casts are simply too powerful (about the same as the dreaded
reinterpret_cast). For instance in some cases you can, with a single typo,
cast one pointer type to a completely different pointer type when all you
meant to do was cast away constness. If you make that mistake with a
const_cast you will get a compile time error.

--
Cy
http://home.rochester.rr.com/cyhome/



Ron Natalie 01-15-2004 04:59 PM

Re: reinterpret_cast<>() v. static_cast<>()
 

"forums_mp" <forums_mp@hotmail.com> wrote in message news:ee300167.0401141842.2695de5e@posting.google.c om...

>
> static_cast is for casting a base class to a derived class. No
> runtime type checking is performed so this seems/is inherently
> dangerous, but sometimes if you are stuck with a bad design ...
> unavoidable. You can also cast an int to an enum using static cast,
> as well as a few other things.


This is incomplete. Static cast has lots of other use other than casting
from base to derived.

> dynamic_cast is a "safe" way to cast a base class to a derived class,
> but it requires you to include type information in your build. if at
> runtime, if the cast can't be performed, then the cast returns 0,
> otherwise the cast succeeds and you continue your program.


No, it requires the pointer casted from to be a polymorphic class
in most (but not all cases). If that's what you mean by "including
type information" in your build, fine, but you'd be better off using
the proper terminology.
>
> Along the same lines I have a question.
> Notwithstanding the C++ casts are limited in scope which in my view
> implies (no proof though) that they are safer than the C variant,
> whats the 'real' gain over the C cast? A question that seems to crop
> up with no reasonable answer on my part. I suspect in the grand
> scheme of things casting it's low level bit twiddling on both parts
> (C/C++)


First, the fact that they are limited in scope, means that the compiler will
check inadvertent errors like changing the type when all you mean to do
is change the const etc.... Further as I pointed out in my original response,
the C++ static_, dynamic_ and reinterpret_ casts DO DIFFERENT THINGS
when presented the same casting arguments. The C-Style cast will do combinations
of static, const and reinterpret (as well as a conversion for which there is no
C++ equivalent). Yes, if you think about it, you can determine which one it
will do, but that is frequently fraught with perils.



Jerry Coffin 01-18-2004 05:49 AM

Re: reinterpret_cast<>() v. static_cast<>()
 
In article <ee300167.0401141842.2695de5e@posting.google.com >,
forums_mp@hotmail.com says...

[ ... ]

> reinterpret_cast is ONLY for pointers, of the same constness. You can
> cast a char* to an unsigned char* or any other * with
> reinterpret_cast, but you can't cast off constness with reinterpret
> cast.


IIRC, reinterpret_cast can be used on references as well as pointers.

> const_cast is to cast off constness. If you have a const char* and
> ABSOLUTELY MUST get rid of its constness and KNOW FOR A FACT that that
> operation is safe AND you can't just make a new copy of the buffer ...
> then const_cast is your tool.


const_cast can also be used to modify volatility.

> static_cast is for casting a base class to a derived class. No
> runtime type checking is performed so this seems/is inherently
> dangerous, but sometimes if you are stuck with a bad design ...
> unavoidable. You can also cast an int to an enum using static cast,
> as well as a few other things.


You should almost never use static_cast to cast between different types
in the same hierarchy -- moving up the hierarchy can be done implicitly,
and down the hierarchy should normally use dynamic_cast. static_cast
should normally be used for things like floating->integer.

> dynamic_cast is a "safe" way to cast a base class to a derived class,
> but it requires you to include type information in your build. if at
> runtime, if the cast can't be performed, then the cast returns 0,
> otherwise the cast succeeds and you continue your program.


That's how it works for pointers. For references, dynamic_cast succeeds
or throws and exception.

> Along the same lines I have a question.
> Notwithstanding the C++ casts are limited in scope which in my view
> implies (no proof though) that they are safer than the C variant,
> whats the 'real' gain over the C cast? A question that seems to crop
> up with no reasonable answer on my part. I suspect in the grand
> scheme of things casting it's low level bit twiddling on both parts
> (C/C++)


Anything that tries to talk about "the 'real' gain" is almost certain to
be wrong. There are a number of improvements. dynamic_cast provides a
capability that a C-style cast simply doesn't provide at all.
const_cast provides a capability that a C-style cast could provide, but
is safer since it won't let you accidentally cast to some type that's
totally unrelated to the original type or something like that. From an
entirely different sort of viewpoint, it's essentially impossible to
grep for C-style casts, but trivial to do so for the new C++ casts.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Old Wolf 01-19-2004 09:53 PM

Re: reinterpret_cast<>() v. static_cast<>()
 
> > dynamic_cast is a "safe" way to cast a base class to a derived class,
> > but it requires you to include type information in your build. if at
> > runtime, if the cast can't be performed, then the cast returns 0,
> > otherwise the cast succeeds and you continue your program.

>
> That's how it works for pointers. For references, dynamic_cast succeeds
> or throws and exception.


Is this UB:
class Base { /* ... */ };
class Derived: public Base { public: int bar; };

void foo(Base *b)
{
try {
dynamic_cast<Derived *>(b)->bar = 3;
}
catch(...) {
do_error("non-derived object passed");
}
}

I had previously assumed that this was a safe technique because
the dynamic_cast would throw. But if this is not the case, then
there is UB because of the 0-dereference (it might not even
throw an exception at all).


All times are GMT. The time now is 08:05 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.