Topic: casts


Author: kanze@us-es.sel.de (James Kanze US/ESC 60/3/164 #71425)
Date: 10 Aug 1994 15:40:31 GMT
Raw View
In article <32847h$f7b@ritz.cec.wustl.edu> jaf3@ritz.cec.wustl.edu
(John Andrew Fingerhut) writes:

|> In article <JASON.94Aug8135543@deneb.cygnus.com>,
|> Jason Merrill <jason@cygnus.com> wrote:

|> :The other new cast keywords are subsets of the C cast:

|> :static_cast allows the user to make implicit conversions explicit and to do
|> :  the inverses of the implicit conversions (base->derived, for instance).
|> :reinterpret_cast implies that no attempt should be made to adjust the
|> :  semantics of the object being converted;
|> :  i.e. reinterpret_cast<Base*>(Derivedp) will not adjust the address.
|> :const_cast can only be used to cast away const.

|> Is the old cast equivilent to any of these?

Any given instance of the old cast is equivalent to one or more of
these.  The real fun was guessing which one for a given instance.

|> Multiple of these depending on the
|> situation?  Can you give some examples of static_cast?

Any downcast that you don't want dynamically checked.  (This often
occurs when using templates, for example.)

Any of the legal casts between basic types, e.g.: int->double.

|> I don't follow your
|> explanation at all.  I thought that cast away const was gone with mutable.
|> What is the need for it?



Author: g2devi@cdf.toronto.edu (Robert N. Deviasse)
Date: Thu, 11 Aug 1994 00:21:28 GMT
Raw View
In article <KANZE.94Aug10174032@slsvhdt.us-es.sel.de>,
James Kanze US/ESC 60/3/164 #71425 <kanze@us-es.sel.de> wrote:
>In article <32847h$f7b@ritz.cec.wustl.edu> jaf3@ritz.cec.wustl.edu
>(John Andrew Fingerhut) writes:
>|> I don't follow your
>|> explanation at all.  I thought that cast away const was gone with mutable.
>|> What is the need for it?
>
>From my AssocArray class:
>
> ValueType* find( IndexType const& elem , bool makeNew ) ;
>
>This is a non-const function: if makeNew is true, it inserts a new
>element if it doesn't find the entry, otherwise, it returns NULL.
>
>And the following functions:
>
> bool
> contains( IndexType const& elem ) const
> {
>     return (const_cast< AssocArray* >this)->find( elem , false) != NULL ;
> }
>
>The case is more frequent than you imagine, and mutable doesn't help.

You don't need mutable here. Define:

 LocationInfo find_location( IndexType const& elem) const ;

to be a private function that returns the location (or location data) of
the place to allocate or find the node. LocationInfo also gives information
whether whether or not the node has been found. Then define the following

        // Does the LocationInfo refer to a null node?
        bool is_null(LocationInfo info);

        // Allocate a node where info refers to, and update info.
        void allocate_data(LocationInfo& info,IndexType const& elem);

        // Return the data associated with LocationInfo.
        ValueType* data_of(LocationInfo info);


 ValueType* find( IndexType const& elem , bool makeNew ) {
           LocationInfo info=find_location(elem);
           if (is_null(info) && makeNew)
              allocate_data(info,elem);   // Allocate element and update info
           return data_of(info);
        }


 bool contains( IndexType const& elem ) const {
           return is_null(find_location(elem));
 }


For many collections, you can define  LocationInfo to be just a pointer
to a pointer to a collection node, so there shouldn't really be any overhead
over your method, and you don't have to cheat the type system.

Are there any other cases where const_cast is really needed?

>--
>James Kanze                                  email: kanze@lts.sel.alcatel.de
>GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
>Conseils en informatique industrielle --
>                              -- Beratung in industrieller Datenverarbeitung


Take care
    Robert
--
/----------------------------------+------------------------------------------\
| Robert N. Deviasse               |"If we have to re-invent the wheel,       |
| EMAIL: g2devi@cdf.utoronto.ca    |  can we at least make it round this time"|
+----------------------------------+------------------------------------------/




Author: kanze@us-es.sel.de (James Kanze US/ESC 60/3/164 #71425)
Date: 11 Aug 1994 13:34:02 GMT
Raw View
In article <CuCGzu.MBF@cdf.toronto.edu> g2devi@cdf.toronto.edu (Robert
N. Deviasse) writes:

|> In article <KANZE.94Aug10174032@slsvhdt.us-es.sel.de>,
|> James Kanze US/ESC 60/3/164 #71425 <kanze@us-es.sel.de> wrote:

    [In answer to a question about whether casting away const is needed...]
|> >From my AssocArray class:
|> >
|> > ValueType* find( IndexType const& elem , bool makeNew ) ;
|> >
|> >This is a non-const function: if makeNew is true, it inserts a new
|> >element if it doesn't find the entry, otherwise, it returns NULL.

|> >And the following functions:

|> > bool
|> > contains( IndexType const& elem ) const
|> > {
|> >     return (const_cast< AssocArray* >this)->find( elem , false) != NULL ;
|> > }

|> >The case is more frequent than you imagine, and mutable doesn't help.

|> You don't need mutable here. Define:

|>  LocationInfo find_location( IndexType const& elem) const ;

|> to be a private function that returns the location (or location data) of
|> the place to allocate or find the node.

Agreed.  Perhaps this would be a better design.  But returning a class
object is rarely efficient (in current implementations), and in the
current implementation of AssocArray, it is much more efficient to
insert an object while one is looking it up.

|> For many collections, you can define  LocationInfo to be just a pointer
|> to a pointer to a collection node, so there shouldn't really be any overhead
|> over your method, and you don't have to cheat the type system.

I could do this for AssocArray, but the pointer couldn't *also* carry
the information as to whether the node exists or not.

|> Are there any other cases where const_cast is really needed?

If you allow code duplication, I doubt it.  Just maintain two versions
of the function.  And hope, of course, that they both implement the
same algorithm (including after various updates and modifications in
the future).

But I think your suggestion looks good, and will give it a try.  And
maybe someday, we will get a compiler that will recognize that when
the class object consists of just a bool and a pointer (what my
AssocArray class would nead in LocationInfo), it can be returned in
registers.  Then, there will be no performance penalty, either.
--
James Kanze                                  email: kanze@lts.sel.alcatel.de
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung




Author: pete@genghis.interbase.borland.com (Pete Becker)
Date: Tue, 9 Aug 1994 15:51:57 GMT
Raw View
In article <JASON.94Aug8135543@deneb.cygnus.com>,
Jason Merrill <jason@cygnus.com> wrote:
>
>const_cast can only be used to cast away const.
>

 It's a little more general than that. It can be used to change const
and volatile qualifiers, by adding them or removing them.
 -- Pete





Author: jaf3@ritz.cec.wustl.edu (John Andrew Fingerhut)
Date: 9 Aug 1994 09:35:29 -0500
Raw View
In article <JASON.94Aug8135543@deneb.cygnus.com>,
Jason Merrill <jason@cygnus.com> wrote:
:>>>>> John Andrew Fingerhut <jaf3@ritz.cec.wustl.edu> writes:
:
:> I have been trying to figure out the syntax and meanings of the new cast
:> keywords/operators.  The copy of Stroustrups "The C++ Programming Language"
:> that I have only talks about dynamic cast.  I have seen static_cast and
:> reinterpret_cast mentioned in this newsgroup and in comp.lang.c++.  Are there
:> others?  What are their differences and how do they relate to a simple cast
:> operation, i.e. (Derived *) base;?
:
:The other new cast keywords are subsets of the C cast:
:
:static_cast allows the user to make implicit conversions explicit and to do
:  the inverses of the implicit conversions (base->derived, for instance).
:reinterpret_cast implies that no attempt should be made to adjust the
:  semantics of the object being converted;
:  i.e. reinterpret_cast<Base*>(Derivedp) will not adjust the address.
:const_cast can only be used to cast away const.
:
:Jason

Is the old cast equivilent to any of these?  Multiple of these depending on the
situation?  Can you give some examples of static_cast?  I don't follow your
explanation at all.  I thought that cast away const was gone with mutable.
What is the need for it?

Stephen Gevers
sg3235@shelob.sbc.com




Author: kanze@us-es.sel.de (James Kanze US/ESC 60/3/164 #71425)
Date: 09 Aug 1994 14:57:03 GMT
Raw View
In article <325hh6$96s@ritz.cec.wustl.edu> jaf3@ritz.cec.wustl.edu
(John Andrew Fingerhut) writes:

|> I have been trying to figure out the syntax and meanings of the new cast
|> keywords/operators.  The copy of Stroustrups "The C++ Programming Language"
|> that I have only talks about dynamic cast.  I have seen static_cast and
|> reinterpret_cast mentioned in this newsgroup and in comp.lang.c++.  Are there
|> others?  What are their differences and how do they relate to a simple cast
|> operation, i.e. (Derived *) base;?

The other three are: const_cast, static_cast and reinterpret_cast.
Fundamentally, they do nothing more than the old style cast, but...

The old style cast is overloaded.  In C this wasn't a great problem:
pointer casts were reinterpret casts, the others were static casts
(conversion operators), and nobody really cared about const.  (This is
actually a radical simplification of the situation, but this is how
most people thought of them, and it worked on most conventional
architectures.)

In C++, things are more complicated.  Pointer (and reference) old
style casts involve actual type conversion (of the pointer) when
casting up and down in the inheritance DAG, but re-interpret casts
elsewhere.  Change your inheritance lattice, and a static cast
suddenly becomes a reinterpret cast.  (This has been a real problem in
our developments.)  In addition, it is easy to accidentally change
types when casting away const (not fully avoidable, even with the
mutable extension).

The point of the new style casts is that each of the casts will only
do one thing.  So, if a static cast is used within the inheritance
lattice, modifications in the lattice may make it illegal, but they
cannot silently change it into a reinterpret cast.
--
James Kanze                                  email: kanze@lts.sel.alcatel.de
GABI Software, Sarl., 8 rue des Francs Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung




Author: jaf3@ritz.cec.wustl.edu (John Andrew Fingerhut)
Date: 8 Aug 1994 10:04:06 -0500
Raw View
I have been trying to figure out the syntax and meanings of the new cast
keywords/operators.  The copy of Stroustrups "The C++ Programming Language"
that I have only talks about dynamic cast.  I have seen static_cast and
reinterpret_cast mentioned in this newsgroup and in comp.lang.c++.  Are there
others?  What are their differences and how do they relate to a simple cast
operation, i.e. (Derived *) base;?

Stephen Gevers
sg3235@shelob.sbc.com




Author: jason@cygnus.com (Jason Merrill)
Date: Mon, 8 Aug 1994 20:55:43 GMT
Raw View
>>>>> John Andrew Fingerhut <jaf3@ritz.cec.wustl.edu> writes:

> I have been trying to figure out the syntax and meanings of the new cast
> keywords/operators.  The copy of Stroustrups "The C++ Programming Language"
> that I have only talks about dynamic cast.  I have seen static_cast and
> reinterpret_cast mentioned in this newsgroup and in comp.lang.c++.  Are there
> others?  What are their differences and how do they relate to a simple cast
> operation, i.e. (Derived *) base;?

The other new cast keywords are subsets of the C cast:

static_cast allows the user to make implicit conversions explicit and to do
  the inverses of the implicit conversions (base->derived, for instance).
reinterpret_cast implies that no attempt should be made to adjust the
  semantics of the object being converted;
  i.e. reinterpret_cast<Base*>(Derivedp) will not adjust the address.
const_cast can only be used to cast away const.

Jason