Topic: static_cast vs. reinterpret_cast


Author: andreytarasevich@hotmail.com (Andrey Tarasevich)
Date: Tue, 3 Sep 2002 16:41:29 +0000 (UTC)
Raw View
Victor Bazarov wrote:
> ...
> Such conversion (from char* to int*) may only be defined for
> keeping the pointer value and converting it back.

Actually, if alignment requirements of types 'char' and 'int' are
different, there is no guarantee that I'll get back the original pointer
value after "round trip" conversion 'char* -> int* ->char*'. But that's
not the question.

> You will
> not be able to use any 'int' values unless the alignment
> requirements of 'char' and 'int' are the same on your platform.
> If they _are_ the same, then reinterpret_cast is just what you
> need.  Unless, of course, I am misreading paragraph 7 of 5.2.10.
>

What makes you think that I'll be able to use it this way? All that the
standard says, is that mapping is implementation defined (no matter what
the alignment requirements are). I wish the standard would say something
like "If alignment requirements of the destination type are not stronger
than those of the source type, 'reinterpret_cast' produces a pointer
that points to the same memory location as the source pointer". But it
doesn't say anything of that nature. "Mapping is implementation defined"
- that's it. Under this circumstances the only platform-independent use
for 'reinterpret_cast' is the aforementioned "round trip" conversion. It
doesn't seem to be very useful.

Best regards,
Andrey Tarasevich,
Brainbench C and C++ Programming MVP

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 28 Aug 2002 17:50:15 GMT
Raw View
"Andrey Tarasevich" <andreytarasevich@hotmail.com> wrote in message
news:3D235CB9.59DD19FD@hotmail.com...
> John Potter wrote:
> > ...
> > > > >e.g.:
> > > > >int* p = static_cast<int*>(malloc(size));
> > > > >or
> > > > >int* p = reinterpret_cast<int*>(malloc(size));
> >
> > > > static_cast.  If there's a difference in representation betwen int*
and
> > > > void*, you need to perform that conversion, which reinterpret_cast
won't
> > > > do.
> >
> > > 'reinterpret_cast' _will_ do the conversion correctly even if there is
a
> > > difference in representation between 'int*' and 'void*'. Types 'int'
and
> > > 'void' are unrelated. Therefore 'reinterpret_cast' is more appropriate
> > > than 'static_cast' in this case.
> >
> > I don't think so.  Note that conversion from pointer to void to
> > pointer to object type is listed as a static_cast and is not listed as
> > a reinterpret_cast.  A cast expression will be translated as a
> > static_cast.  Void is not an object type.  Did I miss something in
> > 5.2.10?
> > ...
>
> Hmm... OK, you are right. The standard doesn't specify the result of
> such 'reinterpet_cast' anyway (except 9.2/17). However, this has nothing
> to do with the difference in internal representation of the pointers.
> The standard doesn't prevent 'reinterpret_cast' from adjusting the
> pointer representation.
>
> One thing is still bugging me. Let's say a allocated an array of 'char's
> using array form of new-expression. The amount of memory allocated is
> enough to hold, say, array of 5 objects of type 'int':
>
> char* raw = new char[sizeof(int) * 5];
>
> Now I'd like to interpret this memory as an array of 5 'int's. Which
> type of cast am I supposed to use? 'static_cast' will not perform
> conversion from 'char*' to 'int*'. The result of 'reinterpret_cast' in
> unspecified. (C-style cast will be interpreted as 'reinterpret_cast').
> This automatically means that the result of the following conversion is
> unspecified too:
>
> int* pi = (int*) raw;
>
> If I wanted to use this memory for an array of objects of class type
> with non-trivial constructor, I would use placement new to construct
> each element. Placement new would both construct the elements and
> perform the 'raw memory' -> 'object pointer' conversion for me (the
> result of the very first placement new). I'm not supposed to care how
> this conversion was done. Of course, I can do the same thing in order to
> build an array of 'int's. But this looks like an overkill. The lifetime
> of an 'int' object starts immediately when storage is obtained. There's
> no need to invoke placement new in this case.
>
> So, what's the right way to perform this conversion?


Such conversion (from char* to int*) may only be defined for
keeping the pointer value and converting it back.  You will
not be able to use any 'int' values unless the alignment
requirements of 'char' and 'int' are the same on your platform.

If they _are_ the same, then reinterpret_cast is just what you
need.  Unless, of course, I am misreading paragraph 7 of 5.2.10.

Victor
--
Please remove capital A's from my address when replying by mail


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Roger Orr" <rogero@howzatt.demon.co.uk>
Date: Tue, 9 Jul 2002 18:29:37 GMT
Raw View
Andrey Tarasevich wrote in message <3D235CB9.59DD19FD@hotmail.com>...
[snip]
>One thing is still bugging me. Let's say a allocated an array of 'char's
>using array form of new-expression. The amount of memory allocated is
>enough to hold, say, array of 5 objects of type 'int':
>
>char* raw = new char[sizeof(int) * 5];
>
>Now I'd like to interpret this memory as an array of 5 'int's. Which
>type of cast am I supposed to use? 'static_cast' will not perform
>conversion from 'char*' to 'int*'.

I usually keep addresses like this as void *.

void *raw = new char[ sizeof(int) * 5];

(or even
void *raw = ::operator new( sizeof(int) * 5 );
since I'm only after raw memory)

int * pi = static_cast<int*>( raw );

Hope this helps.
--
Roger Orr
MVP in C++ at www.brainbench.com


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 2 Jul 2002 22:56:19 GMT
Raw View
In article <3D21F352.80B13661@hotmail.com>, Andrey Tarasevich
<andreytarasevich@hotmail.com> writes
>'reinterpret_cast' _will_ do the conversion correctly even if there is a
>difference in representation between 'int*' and 'void*'. Types 'int' and
>'void' are unrelated. Therefore 'reinterpret_cast' is more appropriate
>than 'static_cast' in this case.

actually I think that int* and void* ARE related because there is an
implicit cast from int* to void*. static_cast is the appropriate
mechanism to explicitly go in the reverse direction.

--
Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Carl Daniel" <cpdaniel@pacbell.net>
Date: Wed, 3 Jul 2002 00:12:19 GMT
Raw View
"Frank A. Uepping" <Frank.Uepping@t-online.de> wrote in message
news:3D1DFD91.6EDFC6A7@t-online.de...
> what is more appropriate/correct for casting a void* to a concrete
pointer?
>
> e.g.:
> int* p = static_cast<int*>(malloc(size));
> or
> int* p = reinterpret_cast<int*>(malloc(size));

My rule of thumb is this:  reinterpret_cast is only appropriate where it's
the only cast which will work (other than a C-style cast, which is {nearly}
never appropriate).

-cd


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Wed, 3 Jul 2002 00:20:55 GMT
Raw View
On Tue,  2 Jul 2002 20:01:00 GMT, Andrey Tarasevich
<andreytarasevich@hotmail.com> wrote:

> Barry Margolin wrote:

> > >what is more appropriate/correct for casting a void* to a concrete pointer?

> > >e.g.:
> > >int* p = static_cast<int*>(malloc(size));
> > >or
> > >int* p = reinterpret_cast<int*>(malloc(size));

> > static_cast.  If there's a difference in representation betwen int* and
> > void*, you need to perform that conversion, which reinterpret_cast won't
> > do.

> 'reinterpret_cast' _will_ do the conversion correctly even if there is a
> difference in representation between 'int*' and 'void*'. Types 'int' and
> 'void' are unrelated. Therefore 'reinterpret_cast' is more appropriate
> than 'static_cast' in this case.

I don't think so.  Note that conversion from pointer to void to
pointer to object type is listed as a static_cast and is not listed as
a reinterpret_cast.  A cast expression will be translated as a
static_cast.  Void is not an object type.  Did I miss something in
5.2.10?

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jpotter@falcon.lhup.edu (John Potter)
Date: Wed, 3 Jul 2002 16:11:00 GMT
Raw View
On Tue,  2 Jul 2002 20:01:00 GMT, Andrey Tarasevich
<andreytarasevich@hotmail.com> wrote:

> Barry Margolin wrote:

> > >what is more appropriate/correct for casting a void* to a concrete pointer?

> > >e.g.:
> > >int* p = static_cast<int*>(malloc(size));
> > >or
> > >int* p = reinterpret_cast<int*>(malloc(size));

> > static_cast.  If there's a difference in representation betwen int* and
> > void*, you need to perform that conversion, which reinterpret_cast won't
> > do.

> 'reinterpret_cast' _will_ do the conversion correctly even if there is a
> difference in representation between 'int*' and 'void*'. Types 'int' and
> 'void' are unrelated. Therefore 'reinterpret_cast' is more appropriate
> than 'static_cast' in this case.

I don't think so.  Note that conversion from pointer to void to
pointer to object type is listed as a static_cast and is not listed as
a reinterpret_cast.  A cast expression will be translated as a
static_cast.  Void is not an object type.  Did I miss something in
5.2.10?

John

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Andrey Tarasevich <andreytarasevich@hotmail.com>
Date: Wed, 3 Jul 2002 20:26:19 GMT
Raw View
John Potter wrote:
> ...
> > > >e.g.:
> > > >int* p = static_cast<int*>(malloc(size));
> > > >or
> > > >int* p = reinterpret_cast<int*>(malloc(size));
>
> > > static_cast.  If there's a difference in representation betwen int* and
> > > void*, you need to perform that conversion, which reinterpret_cast won't
> > > do.
>
> > 'reinterpret_cast' _will_ do the conversion correctly even if there is a
> > difference in representation between 'int*' and 'void*'. Types 'int' and
> > 'void' are unrelated. Therefore 'reinterpret_cast' is more appropriate
> > than 'static_cast' in this case.
>
> I don't think so.  Note that conversion from pointer to void to
> pointer to object type is listed as a static_cast and is not listed as
> a reinterpret_cast.  A cast expression will be translated as a
> static_cast.  Void is not an object type.  Did I miss something in
> 5.2.10?
> ...

Hmm... OK, you are right. The standard doesn't specify the result of
such 'reinterpet_cast' anyway (except 9.2/17). However, this has nothing
to do with the difference in internal representation of the pointers.
The standard doesn't prevent 'reinterpret_cast' from adjusting the
pointer representation.

One thing is still bugging me. Let's say a allocated an array of 'char's
using array form of new-expression. The amount of memory allocated is
enough to hold, say, array of 5 objects of type 'int':

char* raw = new char[sizeof(int) * 5];

Now I'd like to interpret this memory as an array of 5 'int's. Which
type of cast am I supposed to use? 'static_cast' will not perform
conversion from 'char*' to 'int*'. The result of 'reinterpret_cast' in
unspecified. (C-style cast will be interpreted as 'reinterpret_cast').
This automatically means that the result of the following conversion is
unspecified too:

int* pi = (int*) raw;

If I wanted to use this memory for an array of objects of class type
with non-trivial constructor, I would use placement new to construct
each element. Placement new would both construct the elements and
perform the 'raw memory' -> 'object pointer' conversion for me (the
result of the very first placement new). I'm not supposed to care how
this conversion was done. Of course, I can do the same thing in order to
build an array of 'int's. But this looks like an overkill. The lifetime
of an 'int' object starts immediately when storage is obtained. There's
no need to invoke placement new in this case.

So, what's the right way to perform this conversion?

Best regards,
Andrey Tarasevich,
Brainbench C and C++ Programming MVP

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Barry Margolin <barmar@genuity.net>
Date: Mon, 1 Jul 2002 23:01:42 GMT
Raw View
In article <3D1DFD91.6EDFC6A7@t-online.de>,
Frank A. Uepping <Frank.Uepping@t-online.de> wrote:
>what is more appropriate/correct for casting a void* to a concrete pointer?
>
>e.g.:
>int* p = static_cast<int*>(malloc(size));
>or
>int* p = reinterpret_cast<int*>(malloc(size));

static_cast.  If there's a difference in representation betwen int* and
void*, you need to perform that conversion, which reinterpret_cast won't
do.

--
Barry Margolin, barmar@genuity.net
Genuity, Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Andrey Tarasevich <andreytarasevich@hotmail.com>
Date: Tue, 2 Jul 2002 20:01:00 GMT
Raw View
Barry Margolin wrote:
> ...
> >what is more appropriate/correct for casting a void* to a concrete pointer?
> >
> >e.g.:
> >int* p = static_cast<int*>(malloc(size));
> >or
> >int* p = reinterpret_cast<int*>(malloc(size));
>
> static_cast.  If there's a difference in representation betwen int* and
> void*, you need to perform that conversion, which reinterpret_cast won't
> do.
> ...

'reinterpret_cast' _will_ do the conversion correctly even if there is a
difference in representation between 'int*' and 'void*'. Types 'int' and
'void' are unrelated. Therefore 'reinterpret_cast' is more appropriate
than 'static_cast' in this case.

Best regards,
Andrey Tarasevich,
Brainbench C and C++ Programming MVP

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Frank A. Uepping" <Frank.Uepping@t-online.de>
Date: Mon, 1 Jul 2002 22:10:59 GMT
Raw View
what is more appropriate/correct for casting a void* to a concrete pointer?

e.g.:
int* p = static_cast<int*>(malloc(size));
or
int* p = reinterpret_cast<int*>(malloc(size));


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]