473,396 Members | 1,774 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

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.
Jul 22 '05 #1
11 5107
On Tue, 13 Jan 2004 13:53:48 -0800 in comp.lang.c++, "Scott Brady
Drummonds" <sc**********************@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.
Jul 22 '05 #2

"Scott Brady Drummonds" <sc**********************@intel.com> wrote in message news:bu**********@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.
Jul 22 '05 #3

"Scott Brady Drummonds" <sc**********************@intel.com> wrote in
message news:bu**********@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
Jul 22 '05 #4

"Ron Natalie" <ro*@sensor.com> wrote in message
news:40***********************@news.newshosting.co m...

"Scott Brady Drummonds" <sc**********************@intel.com> wrote in message news:bu**********@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
Jul 22 '05 #5
"Scott Brady Drummonds" <sc**********************@intel.com> wrote in message news:<bu**********@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++)

----------
Jul 22 '05 #6
[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/
Jul 22 '05 #7

"forums_mp" <fo*******@hotmail.com> wrote in message news:ee**************************@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.
Jul 22 '05 #8
In article <ee**************************@posting.google.com >,
fo*******@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.
Jul 22 '05 #9
> > 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).
Jul 22 '05 #10

"Old Wolf" <ol*****@inspire.net.nz> wrote in message news:84**************************@posting.google.c om...
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).


Correct.

Jul 22 '05 #11

"Old Wolf" <ol*****@inspire.net.nz> wrote in message
news:84**************************@posting.google.c om...
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).


It can never throw an exception (except in the sense that theoretically it
could
because deref. 0 is UB).

You want:

dynamic_cast<Derived&>(*b).bar = 3;

or replace the whole thing with:

if( Dervived* dp = dynamic_cast<Derived*>(b))
{
dp->bar = 3;
}
else
do_error(.....);

P.S. unless you add one or more virtual methods
to Base dynamic_cast will
not work for you anyway - it will just do the same as
static_cast which will NEVER return null (unless b is).
Jul 22 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

15
by: Aman | last post by:
Hi, wrote this piece of code on SunOS 5.9 , compiler g++ 2.95.3 trying to see the byte order of an int or short int by converting to char* . doesn't work . the char* cpt doesn't seem to be...
3
by: Nate Barney | last post by:
I have: // base class for Vector and Matrix template <unsigned N,typename Value=float> class NonScalar { public: Value *ptr() { return e; } const Value *ptr() const { return e; }
27
by: Noah Roberts | last post by:
What steps do people take to make sure that when dealing with C API callback functions that you do the appropriate reinterpret_cast<>? For instance, today I ran into a situation in which the wrong...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.