Which casting conversion to use for void*?

I

Ian Collins

Or you write your own custom wrappers.

I do write a lot of wrappers, hence the frequent use of reinterpret_cast!
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.

No, too painful.... Invasive and old-fashioned sums it up pretty well!
 
A

Alf P. Steinbach /Usenet

* Stuart Redmann, on 10.05.2011 08:44:
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

The problem arises when you have to use a cast, i.e. you don't control the code
of the derived class and it doesn't offer the required access. For example, you
might want to do this during debugging. Or for unit-testing.

Then a C style cast can correctly cast to inaccessible base as if a static_cast
were used and had access to the base.

This includes pointer value adjustment, if needed.

I do not know what other "certain, very rare conditions" Noah refers to.

As far as the C++ standard is concerned casting to inaccessible base is the only
thing a C style cast can actively do that named casts cannot. On the passive
side, a C style cast can change behavior when the relevant types change (e.g.
from const_cast to reinterpret_cast), but presumbably that's not it. However, I
guess some compiler might implement other casting functionality as a language
extension.


Cheers & hth.,

- Alf
 
D

Dombo

Op 10-May-11 10:20, Ian Collins schreef:
I do write a lot of wrappers, hence the frequent use of reinterpret_cast!


No, too painful.... Invasive and old-fashioned sums it up pretty well!

And yet some parts are surprisingly immature (buggy/sloppy implemented)
for such an old library. But if you like nineties style C++ and yet
another C++ library with its own string and container classes you
probably like ACE. Personally I would consider other options first
before considering ACE; my memories of ACE aren't that pleasant as well.
 
S

Stuart Redmann

The problem arises when you have to use a cast, i.e. you don't control the code
of the derived class and it doesn't offer the required access. For example, you
might want to do this during debugging. Or for unit-testing.

Then a C style cast can correctly cast to inaccessible base as if a static_cast
were used and had access to the base.

This includes pointer value adjustment, if needed.

I do not know what other "certain, very rare conditions" Noah refers to.

As far as the C++ standard is concerned casting to inaccessible base is the only
thing a C style cast can actively do that named casts cannot. On the passive
side, a C style cast can change behavior when the relevant types change (e.g.
from const_cast to reinterpret_cast), but presumbably that's not it. However, I
guess some compiler might implement other casting functionality as a language
extension.

I'd consider such a cast as serious defective (well, OK for debugging
purposes).
IOW, C style casts allows to shoot oneself in the foot to a much
greater extent ;-)

Thanks for the clarification,
Stuart
 
T

ThosRTanner

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

Shouldn't that last line be b = foo(static_cast said:
The last row is equivalent to b = reinterpret_cast<B*>(a); without the cast
actually present in the code.

Somewhere or other I've seen advice to use
static_cast<B*>(static_cast<void*>(a));

in preference to using reinterpret_cast, on the basis it's safer.
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.

void * and casts can be horribly overused. I've seen a class that
could only deal with a certain layout of data, but it still had a void
* constructor and a lot of casting to the only supported type
internally.

Replacing the void * with the correct type uncovered more than one
place where the wrong data was passed in.
 
J

Jorgen Grahn

Op 10-May-11 10:20, Ian Collins schreef:

And yet some parts are surprisingly immature (buggy/sloppy implemented)
for such an old library. But if you like nineties style C++ and yet
another C++ library with its own string and container classes you
probably like ACE. Personally I would consider other options first
before considering ACE; my memories of ACE aren't that pleasant as well.

Thanks. "Nineties-style C++" was actually the third prejudice I had
against it.

/Jorgen
 
K

Kai-Uwe Bux

Jorgen said:
Thanks. "Nineties-style C++" was actually the third prejudice I had
against it.

Just curious: what are the main characteristics of "nineties-style C++"?


Best,

Kai-Uwe Bux
 
Ö

Öö Tiib

Just curious: what are the main characteristics of "nineties-style C++"?


Style like of all C++ frameworks that work. Low usage of namespaces
and so there are prefixes ("old fashioned"), low usage of templates
("invasive"), remarkable usage of preprocessor ("legacy") or code-
generating tools (again all the bad names).

Large and wide framework because reliable and portable standard
library is assumed to be missing. So most bricks (these things are
made of) are present in framework. Significant part of these bricks
are reinvented for supporting concurrency and interprocess
communication. Concurrency is OTW into C++ language two decades after
it was needed so no wonder. Likewise boost defines its own containers
and smart pointers for networking.

I suggested ACE as one of several available and working alternatives
to raw chewing of C socket API or the like that Ian Collins described
like main reason why his C++ code is pile of unmaintainable
'(sockaddr*)&s_addr' crap. I nowhere said that ACE is single available
shiny and modern way out of it.
 
J

Jorgen Grahn

Just curious: what are the main characteristics of "nineties-style C++"?

It's not as if I have a formal definition, but to me it's roughly:

- heavy use of inheritance, little use of templates
- heavy use of raw pointers and heap allocation
- much attention to the big, heavy objects, not enough
attention to the small, shortlived "concrete classes"
- not compatible with the STL

Once again, I don't know anything about ACE myself.

/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,776
Messages
2,569,603
Members
45,189
Latest member
CryptoTaxSoftware

Latest Threads

Top