Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Which casting conversion to use for void*? (http://www.velocityreviews.com/forums/t747972-which-casting-conversion-to-use-for-void.html)

Nephi Immortal 05-08-2011 10:44 PM

Which casting conversion to use for void*?
 
Which should I use correct casting conversion after I create void
variables?

For example:

void *memory = malloc( 0x1000 );

char *pString = static_cast< char* >( memory );

or

char *pString = reinterpret_cast< char* >( memory );


After I deallocate the memory, I will convert from char* back to
void* prior free( void* ) function.

Ian Collins 05-08-2011 10:48 PM

Re: Which casting conversion to use for void*?
 
On 05/ 9/11 10:44 AM, Nephi Immortal wrote:
> Which should I use correct casting conversion after I create void
> variables?


You never create void variables!

> For example:
>
> void *memory = malloc( 0x1000 );
>
> char *pString = static_cast< char*>( memory );
>
> or
>
> char *pString = reinterpret_cast< char*>( memory );


static_cast.

--
Ian Collins

Qi 05-09-2011 06:31 AM

Re: Which casting conversion to use for void*?
 
On 2011-5-9 6:44, Nephi Immortal wrote:
> Which should I use correct casting conversion after I create void
> variables?
>
> For example:
>
> void *memory = malloc( 0x1000 );
>
> char *pString = static_cast< char*>( memory );
>
> or
>
> char *pString = reinterpret_cast< char*>( memory );
>
>
> After I deallocate the memory, I will convert from char* back to
> void* prior free( void* ) function.


*static_cast* until compiler complains. Then use reinterpret_cast.
static_cast is type safe cast, reinterpret_cast not.


--
WQ

Martijn van Buul 05-09-2011 08:04 AM

Re: Which casting conversion to use for void*?
 
* Qi:
> static_cast is type safe cast


It's not. static_cast works for *related* types, but doesn't guarantee
the cast will be safe.

It's safer than reinterpret_cast, but not safe.

--
Martijn van Buul - pino@dohd.org

Balog Pal 05-09-2011 08:44 AM

Re: Which casting conversion to use for void*?
 
"Nephi Immortal" <immortalnephi@gmail.com>
> Which should I use correct casting conversion after I create void
> variables?
> void *memory = malloc( 0x1000 );
> char *pString = static_cast< char* >( memory );
> char *pString = reinterpret_cast< char* >( memory );


The general sugestion is to use static_cast wherever it compiles, and
reinterpret otherwise.
static_cast works to upcast void* to anything -- what probably made sense
for some contexts but IMO is more hurtful. As you can lose type info easily:

A* a;
B* b;
B* foo(void * p) { return static_cast<B*>(p);}
b = foo(a);

The last row is equivalent to b = reinterpret_cast<B*>(a); without the cast
actually present in the code.

For these reasons I suggest to use static_cast to deal with input that is
"genuinely" void/typeless, like that malloc. And use reinterpret_cast when
your input was originally typed, and you're not sure. For surefire,
nonmissable cases static_cast is okay again -- like you have an enum and a
void*, and the enum tells you the original type at store.

Certainly in a good program you should be sure everywhere -- as you go
eventually can get rid of all reinterpret_cast cases -- until then it is
easy to locate them.


Noah Roberts 05-09-2011 04:21 PM

Re: Which casting conversion to use for void*?
 
On 5/8/2011 11:31 PM, Qi wrote:
> On 2011-5-9 6:44, Nephi Immortal wrote:
>> Which should I use correct casting conversion after I create void
>> variables?
>>
>> For example:
>>
>> void *memory = malloc( 0x1000 );
>>
>> char *pString = static_cast< char*>( memory );
>>
>> or
>>
>> char *pString = reinterpret_cast< char*>( memory );
>>
>>
>> After I deallocate the memory, I will convert from char* back to
>> void* prior free( void* ) function.

>
> *static_cast* until compiler complains. Then use reinterpret_cast.
> static_cast is type safe cast, reinterpret_cast not.


I can't say I recommend this procedure. It can easily lead people to
cast when they don't have to. For example, I found code like this in a
project I worked on:

// whatnot.h

struct A
struct B

struct whatnot
{
A* a;
void fun(B* b) { a = (B*)b; }
};

// B.h

#include "A.h"

struct B : A {....};

Of course, it's quite silly to do an upcast like this. It's even worse
to do a C-style cast. What's even worse than that about it is that this
particular cast will be a reinterpret_cast.

The reason of course that it was done is almost certainly that the
compiler complained about unrelated types and recommended a reinterpret
or C-style cast (the MS compiler does this). A more appropriate
solution of course is to include the appropriate headers and/or move the
body of f() into a cpp file.

So, it's not really a well recommended practice in my opinion to plug in
reinterpret_cast when the compiler starts to bitch. This cast should
really be reserved for very special cases and, in fact, with almost all
modern C++ it's completely unnecessary.

--
http://crazycpp.wordpress.com

Joshua Maurice 05-09-2011 06:34 PM

Re: Which casting conversion to use for void*?
 
On May 9, 9:21*am, Noah Roberts <d...@email.me> wrote:
> On 5/8/2011 11:31 PM, Qi wrote:
>
>
>
> > On 2011-5-9 6:44, Nephi Immortal wrote:
> >> Which should I use correct casting conversion after I create void
> >> variables?

>
> >> For example:

>
> >> void *memory = malloc( 0x1000 );

>
> >> char *pString = static_cast< char*>( memory );

>
> >> or

>
> >> char *pString = reinterpret_cast< char*>( memory );

>
> >> After I deallocate the memory, I will convert from char* back to
> >> void* prior free( void* ) function.

>
> > *static_cast* until compiler complains. Then use reinterpret_cast.
> > static_cast is type safe cast, reinterpret_cast not.

>
> I can't say I recommend this procedure. *It can easily lead people to
> cast when they don't have to. *For example, I found code like this in a
> project I worked on:
>
> // whatnot.h
>
> struct A
> struct B
>
> struct whatnot
> {
> * *A* a;
> * *void fun(B* b) { a = (B*)b; }
>
> };
>
> // B.h
>
> #include "A.h"
>
> struct B : A {....};
>
> Of course, it's quite silly to do an upcast like this. *It's even worse
> to do a C-style cast. *What's even worse than that about it is that this
> particular cast will be a reinterpret_cast.
>
> The reason of course that it was done is almost certainly that the
> compiler complained about unrelated types and recommended a reinterpret
> or C-style cast (the MS compiler does this). *A more appropriate
> solution of course is to include the appropriate headers and/or move the
> body of f() into a cpp file.
>
> So, it's not really a well recommended practice in my opinion to plug in
> reinterpret_cast when the compiler starts to bitch. *This cast should
> really be reserved for very special cases and, in fact, with almost all
> modern C++ it's completely unnecessary.


I thank you for that example, which is quite similar to the one that I
like to use.

However, let me possibly take a slightly different stance though. In C+
+ code, you should never use the C-style cast for casting with class
types. In all cases, the C-style cast is equivalent to either a
static_cast or a reinterpret_cast, and as you have pointed out, it can
be quite "ambiguous", or hard to tell for a human reader, which it is
when working with class types. It's error prone. That's why I suggest
writing what you mean and write either the static_cast or the
reinterpret_cast.

Having said that, reinterpret_cast is almost never needed, so I don't
"like" when I see it. However, sometimes you do need it, and I much
prefer to see a reinterpret_cast over a C-style which is in effect
doing a reinterpret_cast on class types.

Noah Roberts 05-09-2011 07:48 PM

Re: Which casting conversion to use for void*?
 
On 5/9/2011 11:34 AM, Joshua Maurice wrote:
> On May 9, 9:21 am, Noah Roberts<d...@email.me> wrote:
>> On 5/8/2011 11:31 PM, Qi wrote:
>>
>>
>>
>>> On 2011-5-9 6:44, Nephi Immortal wrote:
>>>> Which should I use correct casting conversion after I create void
>>>> variables?

>>
>>>> For example:

>>
>>>> void *memory = malloc( 0x1000 );

>>
>>>> char *pString = static_cast< char*>( memory );

>>
>>>> or

>>
>>>> char *pString = reinterpret_cast< char*>( memory );

>>
>>>> After I deallocate the memory, I will convert from char* back to
>>>> void* prior free( void* ) function.

>>
>>> *static_cast* until compiler complains. Then use reinterpret_cast.
>>> static_cast is type safe cast, reinterpret_cast not.

>>
>> I can't say I recommend this procedure. It can easily lead people to
>> cast when they don't have to. For example, I found code like this in a
>> project I worked on:
>>
>> // whatnot.h
>>
>> struct A
>> struct B
>>
>> struct whatnot
>> {
>> A* a;
>> void fun(B* b) { a = (B*)b; }
>>
>> };
>>
>> // B.h
>>
>> #include "A.h"
>>
>> struct B : A {....};
>>
>> Of course, it's quite silly to do an upcast like this. It's even worse
>> to do a C-style cast. What's even worse than that about it is that this
>> particular cast will be a reinterpret_cast.
>>
>> The reason of course that it was done is almost certainly that the
>> compiler complained about unrelated types and recommended a reinterpret
>> or C-style cast (the MS compiler does this). A more appropriate
>> solution of course is to include the appropriate headers and/or move the
>> body of f() into a cpp file.
>>
>> So, it's not really a well recommended practice in my opinion to plug in
>> reinterpret_cast when the compiler starts to bitch. This cast should
>> really be reserved for very special cases and, in fact, with almost all
>> modern C++ it's completely unnecessary.

>
> I thank you for that example, which is quite similar to the one that I
> like to use.
>
> However, let me possibly take a slightly different stance though. In C+
> + code, you should never use the C-style cast for casting with class
> types. In all cases, the C-style cast is equivalent to either a
> static_cast or a reinterpret_cast


This is not actually true. There are certain, very rare conditions in
which a C-style cast does not match any of the available new-style casts
and is absolutely necessary for the specific cast needed. Correctly
casting to a protected/private base class for example; although it's
extremely rare that you'd want to do this, when you do a C-style cast is
necessary.

, and as you have pointed out, it can
> be quite "ambiguous", or hard to tell for a human reader, which it is
> when working with class types. It's error prone. That's why I suggest
> writing what you mean and write either the static_cast or the
> reinterpret_cast.


Although my example uses a C-Style cast, it would fall afoul of error
when applying Qi's rule, "use static_cast until the compiler complains,
then use reinterpret_cast." The author of the code in question probably
thought they where doing a static cast, and it's only because a static
cast would not work there that a reinterpret cast is the actual result.

--
http://crazycpp.wordpress.com

Ian Collins 05-09-2011 08:02 PM

Re: Which casting conversion to use for void*?
 
On 05/10/11 04:21 AM, Noah Roberts wrote:
>
> So, it's not really a well recommended practice in my opinion to plug in
> reinterpret_cast when the compiler starts to bitch. This cast should
> really be reserved for very special cases and, in fact, with almost all
> modern C++ it's completely unnecessary.


While I agree in theory, a lot of my nice shiny modern C++ had to deal
with C interfaces. Try using BSD socket and name service functions
without a smattering of reinterpret_casts.

--
Ian Collins

Öö Tiib 05-09-2011 08:44 PM

Re: Which casting conversion to use for void*?
 
On May 9, 9:34*pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
>
>
> In all cases, the C-style cast is equivalent to either a
> static_cast or a reinterpret_cast, and as you have pointed out, it can
> be quite "ambiguous", or hard to tell for a human reader, which it is
> when working with class types.


Nitpick ... in all cases C-style cast is either a static_cast,
dynamic_cast, const_cast, reinterpret_cast or combination of such.

That of course strengthens the rest of your points even more.


All times are GMT. The time now is 11:19 AM.

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