Which casting conversion to use for void*?

N

Nephi Immortal

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

Ian Collins

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

Qi

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

Martijn van Buul

* 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.
 
B

Balog Pal

Nephi Immortal said:
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.
 
N

Noah Roberts

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

Joshua Maurice

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

Noah Roberts

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

Ian Collins

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

Öö Tiib

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

Öö Tiib

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.

Yes but lot of these C things have C++ wrappers. Instead of raw C
networking most aim something like ACE, boost::asio, QDataStream
etc ... it is more typesafe and portable.
 
J

Joshua Maurice

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

const_cast yes, but unless I'm losing my mind, C-style casts can never
be dynamic_casts. Can it? Example please? I was pretty sure no, but
now you're making me question that. Whipping through a couple of
examples, I'm pretty sure no still.
 
J

Joshua Maurice

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.

Well, thank you for teaching me something new. I tested it out on an
available compiler, and it's there in C++03, 5.4 Explicit type
conversion (cast notation) / 7.

That's horrible. I would want a nice glaring comment for any such kind
of cast, if ever required.
 
I

Ian Collins

Yes but lot of these C things have C++ wrappers. Instead of raw C
networking most aim something like ACE, boost::asio, QDataStream
etc ... it is more typesafe and portable.

Ug, why did you have to mention ACE? I got over the nightmares years
ago, now they will come back!
 
Ö

Öö Tiib

const_cast yes, but unless I'm losing my mind, C-style casts can never
be dynamic_casts. Can it? Example please? I was pretty sure no, but
now you're making me question that. Whipping through a couple of
examples, I'm pretty sure no still.

Not sure ... isn't it dynamic_cast like that:

struct OneInterface
{
virtual void one() = 0;
};

struct OtherInterface
{
virtual void other() = 0;
};

class X
: public OneInterface
, public OtherInterface
{
public:
virtual void one() {}
virtual void other() {}
};

int main()
{
OneInterface* p = new X;
p->one();
// static_cast and reinterpret_cast both wrong:
OtherInterface* p2 = (OtherInterface*)p;
p2->other();
}
 
K

Kai-Uwe Bux

Öö Tiib said:
Not sure ... isn't it dynamic_cast like that:

struct OneInterface
{
virtual void one() = 0;
};

struct OtherInterface
{
virtual void other() = 0;
};

class X
: public OneInterface
, public OtherInterface
{
public:
virtual void one() {}
virtual void other() {}
};

int main()
{
OneInterface* p = new X;
p->one();
// static_cast and reinterpret_cast both wrong:
OtherInterface* p2 = (OtherInterface*)p;
p2->other();
}

Assuming that the code compiles (did not check too hard), I think the line

OtherInterface* p2 = (OtherInterface*)p;

is seen by the compiler as a reinterpret_cast as per [5.9/7] and the line

p2->other();

is undefined behavior. In [5.4/5] and [5.4/7], you find a list of what the
cast notation can mean; and a dynamic_cast is not listed.


Best,

Kai-Uwe Bux
 
Ö

Öö Tiib

Assuming that the code compiles (did not check too hard), I think the line

Tried with comeau online ... compiles.
  OtherInterface* p2 = (OtherInterface*)p;

is seen by the compiler as a reinterpret_cast as per [5.9/7] and the line

  p2->other();

is undefined behavior. In [5.4/5] and [5.4/7], you find a list of what the
cast notation can mean; and a dynamic_cast is not listed.

Yes, seems so. Thanks. Lack of dynamic_cast in list is then yet
another reason why not to use C style casts.
 
Q

Qi

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:

IMHO, upon the cast issue, I prefer,

1, Keep cast minimal. Don't abuse using it.
If there are a lot of cast, the design may be wrong.

2, When cast is not avoidable, prefer safer cast to unsafe one.
so prefer static_cast to reinterpret_cast.

3, reinterpret_cast should be rarely used, only used in low level code,
or as other mentioned, mix C code.

4, When RTTI is needed, using dynamic_cast.

Just my 2 cents.
 
S

Stuart Redmann

On 9 Mai, Noah Roberts wrote:

[snip]
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.

[snip]

Could you please elaborate, preferably with an example? The following
works just fine without any C-style cast:

#include <iostream>

class PrivateBase
{
public:
void f ()
{
std::cout << "PrivateBase";
}
};

class PublicDerived : private PrivateBase
{
public:
PrivateBase* GetBase ()
{
return this;
}
};

int main ()
{
PublicDerived pd;
pd.GetBase ()->f ();
return 0;
}

Thanks in advance,
Stuart
 
J

Jorgen Grahn

Or you write your own custom wrappers.
Ug, why did you have to mention ACE? I got over the nightmares years
ago, now they will come back!

Care to expand on that? I have never used ACE, but got the impression
that it's pretty invasive and old-fashioned. Yet you see people
praise it now and then.

/Jorgen
 

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,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top