Topic: Clarification on Casting


Author: baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes)
Date: 1995/07/27
Raw View
Jim Heliotis (heliotis@xerox.com) wrote:
: reinterpret_cast: ignores all type info and simply allows the raw bits to be
:   transferred to an object of the destination type. Common uses:
:    int <--> pointer
:    void * --> ???

In C/C++ these examples are not reinterpret casts. The bits can be manipulated
as part of the type change (though on most architectures they don't change).

The only way to achive a reinterpret cast is to missuse a union or to
access the data via a pointer to it that has been cast to another type.

--
Stephen Baynes                              baynes@mulsoc2.serigate.philips.nl
Philips Semiconductors Ltd
Southampton                                 My views are my own.
United Kingdom





Author: jason@cygnus.com (Jason Merrill)
Date: 1995/07/27
Raw View
>>>>> Stephen Baynes <baynes@ukpsshp1.serigate.philips.nl> writes:

> Jim Heliotis (heliotis@xerox.com) wrote:
> : reinterpret_cast: ignores all type info and simply allows the raw bits to be
> :   transferred to an object of the destination type. Common uses:
> :    int <--> pointer
> :    void * --> ???

> In C/C++ these examples are not reinterpret casts. The bits can be
> manipulated as part of the type change (though on most architectures they
> don't change).

> The only way to achive a reinterpret cast is to missuse a union or to
> access the data via a pointer to it that has been cast to another type.

Please, do not use the term "reinterpret cast" to mean anything other than
the transformation performed by the reinterpret_cast operator;
reinterpret_cast<int>((void*)0) is indeed valid C++.

The operation you are referring to is often called "type punning", I
believe.

Jason





Author: shepherd@debussy.sbi.com (Marc Shepherd)
Date: 1995/07/24
Raw View
In article fsf@phydeaux.cygnus.com, jason@cygnus.com (Jason Merrill) writes:
>>>>>> Fergus Henderson <fjh@munta.cs.mu.OZ.AU> writes:
>
>> There has been some discussion about adding `implicit_cast',
>> which would be the mostly safe subset of `static_cast': implicit conversions.
>> However, even implicit conversions aren't safe - converting a `long'
>> to a `short' may discard information.
>
>There is no need to add implicit_cast to the base language, since it can
>be implemented as a template:
>
>template <class T, class U> inline
>T implicit_cast (U u) { return u; }
>
>....
>
>int i = implicit_cast<int>(1.0);

I agree with the observation that it can be implemented as a template,
but I'd submit that that's not really the issue--there are many things
in the proposed standard that a user could easily implement themselves.

The real question is: is 'implicit_cast' useful enough that we want to
encourage its use and guarantee it's available in a standard way on every
platform?  (I haven't come to a conclusion yet myself--I only point out
that the mere fact that a user could implement it themselves is not sufficient
reason to dismiss it.)


---
Marc Shepherd
Salomon Brothers Inc
shepherd@schubert.sbi.com <<These are my opinions, not my employer's.>>






Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/07/22
Raw View
heliotis@xerox.com (Jim Heliotis) writes:

>dynamic_cast: uses RTTI (run-time type identification) to decide if the cast
>  is legal or not. This only works for polymorphic types.
>  Common use is downcasting: base --> derived.

Yes.  These casts are in general checked at runtime, and you will get
either a null pointer (for a pointer cast) or an exception (for a
reference cast) if the cast is unsafe.

>static_cast: uses type info known at compile time to decide if the cast is
>  legal. If successful, this is still a safe cast. Common uses:
>   upcasting
>   float <--> int

Nope, these casts are *not* safe.  These casts are not checked at runtime.
If you attempt to do

 Base *bp;
 // ...
 Derived *dp = static_cast<Base *>(bp);

and `bp' does not point to a `Derived' object, the result is undefined.

There has been some discussion about adding `implicit_cast',
which would be the mostly safe subset of `static_cast': implicit conversions.
However, even implicit conversions aren't safe - converting a `long'
to a `short' may discard information.

--
Fergus Henderson              | Designing grand concepts is fun;
fjh@cs.mu.oz.au               | finding nitty little bugs is just work.
http://www.cs.mu.oz.au/~fjh   | -- Brooks, in "The Mythical Man-Month".
PGP key fingerprint: 00 D7 A2 27 65 09 B6 AC  8B 3E 0F 01 E7 5D C4 3F





Author: jason@cygnus.com (Jason Merrill)
Date: 1995/07/22
Raw View
>>>>> Fergus Henderson <fjh@munta.cs.mu.OZ.AU> writes:

> There has been some discussion about adding `implicit_cast',
> which would be the mostly safe subset of `static_cast': implicit conversions.
> However, even implicit conversions aren't safe - converting a `long'
> to a `short' may discard information.

There is no need to add implicit_cast to the base language, since it can
be implemented as a template:

template <class T, class U> inline
T implicit_cast (U u) { return u; }

...

int i = implicit_cast<int>(1.0);

Jason





Author: swf@elsegundoca.ncr.com (Stan Friesen)
Date: 1995/07/20
Raw View
In article <3ugvpm$ogm@engnews2.Eng.Sun.COM>, clamage@Eng.Sun.COM (Steve Clamage) writes:
|> No. ...

Sigh. It's been too long since I read "Design and Evoluution ...".

This does point out one potential problem with the new casts - the differences
are subtle, and sometimes confusing.  [I found the language is the draft standard
to be virtually incomprehensible].

--
swf@elsegundoca.attgis.com  sarima@netcom.com

The peace of God be with you.





Author: maxtal@Physics.usyd.edu.au (John Max Skaller)
Date: 1995/07/20
Raw View
In article <9507181651.AA26508@mailhost.ElSegundoCA.ATTGIS.COM>,
Stan Friesen <swf@ElSegundoCA.ATTGIS.COM> wrote:
>In article <dqua.806053811@nntp.earthlink.net>, dqua@earthlink.net (Derick J.R. Qua-Gonzalez) writes:
>|>... I am a little confused
>|> as to the difference and rationale for the existence and purpose of:
>|>
>|> 1) dynamic_cast
>
> A cast which only succeeds if the *true* type of the object is
>the type being cast *to*.  This is useful for casting pointers to base
>classes into pointers to derived classes in such a way that it only succeeds
>if the object really *is* that derived class.

 Unfortunately, that picture is naive. Dynamic casts might work
if the object is of any class type _derived_ from the cast type.
You can also upcast with a dynamic cast, and supposedly cross
cast as well.

>|> 2) static_cast
>
> Treat the object as being the new type without changing the
>bit pattern.

 NO. That is called "reinterpret_cast". static_cast
is the "usual" kind of cast, potentially unsafe and unchecked.

>|> 3) const_cast
>|>
> change the 'const'ness of an object (normally not proper).

 NO kind of cast is "normally proper". Avoid them if possible!
--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,
        81A Glebe Point Rd, GLEBE   Mem: SA IT/9/22,SC22/WG21
        NSW 2037, AUSTRALIA     Phone: 61-2-566-2189





Author: vandevod@avs.cs.rpi.edu (David Vandevoorde)
Date: 1995/07/20
Raw View
In article <3ugvpm$ogm@engnews2.Eng.Sun.COM>,
Steve Clamage <clamage@Eng.Sun.COM> wrote:
>In article AA26508@mailhost.ElSegundoCA.ATTGIS.COM, swf@ElSegundoCA.ATTGIS.COM (Stan Friesen) writes:
>
>Unfortunately, the clarifications provided by Stan are incorrect.
>
>>In article <dqua.806053811@nntp.earthlink.net>, dqua@earthlink.net (Derick J.R. Qua-Gonzalez) writes:
>>|>... I am a little confused
>>|> as to the difference and rationale for the existence and purpose of:
>>|>
>>|> 1) dynamic_cast
>>
>> A cast which only succeeds if the *true* type of the object is
>>the type being cast *to*.  This is useful for casting pointers to base
>>classes into pointers to derived classes in such a way that it only succeeds
>>if the object really *is* that derived class.
>
>No. The cast succeeds if the true type of the object is the target
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>type OR any type derived from that, OR an unambiguous base class of the
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>object type. A dynamic_cast may be applied only to pointers or references,
>and you cannot cast away "const". [5.2.6]
[...]
>Steve Clamage, stephen.clamage@eng.sun.com

For completeness' sake, don't the underlined cases also require that
the argument to dynamic_cast is a pointer or reference to a polymorphic
class ([expr.dynamic.cast], 5.2.6/6)? (A polymorphic class is class
that declares or inherits a virtual function - [class.virtual], 10.3/1.)

 Daveed






Author: dqua@earthlink.net (Derick J.R. Qua-Gonzalez)
Date: 1995/07/18
Raw View
Being mostly a C++ "Classic" person (i.e. as defined in the ARM), I have
only recently started with the ANSI C++ CD (4/95). I am a little confused
as to the difference and rationale for the existence and purpose of:

1) dynamic_cast
2) static_cast
3) const_cast

in light of `plain old' casting.

Can someone please explain this to me? Thank you.

Best regards.
--
+-----------------------------------------------------------------------------+
| Derick R. Qua-Gonzalez                                           | ________ |
| Department of High Energy Physics, California State University   | \      / |
| dqua@Prometheus.EarthLink.Net                                    |  \    /  |
|        ``It is better to be hated for what one is,               |   \  /   |
|          than loved for what one is not.'' (A. Gide)             | G  \/ USA|
+------------------------------------------------------------------+----------+
| mQBNAy/qJJMAAAECANBCB543eTUkdG8Mqx6K2cm3WxCVtKY8ZbB9WY6A2Ne4dQi8 | PGP2.6.2 |
| xh7OxjHXP/eXp5BSbmVAihEGd7r+5g/yknko56kABRG0MERKUiBRdWEtR29uemFs |  Public  |
| ZXogPGRxdWFAUHJvbWV0aGV1cy5FYXJ0aGxpbmsuTmV0Pg==                 | KeyBlock |
| =70DW                                                            | 06.20.95 |
+------------------------------------------------------------------+----------+





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/07/18
Raw View
In article AA26508@mailhost.ElSegundoCA.ATTGIS.COM, swf@ElSegundoCA.ATTGIS.COM (Stan Friesen) writes:

Unfortunately, the clarifications provided by Stan are incorrect.

>In article <dqua.806053811@nntp.earthlink.net>, dqua@earthlink.net (Derick J.R. Qua-Gonzalez) writes:
>|>... I am a little confused
>|> as to the difference and rationale for the existence and purpose of:
>|>
>|> 1) dynamic_cast
>
> A cast which only succeeds if the *true* type of the object is
>the type being cast *to*.  This is useful for casting pointers to base
>classes into pointers to derived classes in such a way that it only succeeds
>if the object really *is* that derived class.

No. The cast succeeds if the true type of the object is the target
type OR any type derived from that, OR an unambiguous base class of the
object type. A dynamic_cast may be applied only to pointers or references,
and you cannot cast away "const". [5.2.6]
Example:
 class A { ... };
 class B : public A { ... };
 class C : public B { ... };
 A* p1 = ...;
 // the following cast succeeds if p1 points to a B or a C or anything
 // else derived from B (or from C, for that matter)
 B* p2 = dynamic_cast<B*>(p1);
 // the following always succeeds; a static_cast would also work
 A* p3 = dynamic_cast<A*>(p2);

>|> 2) static_cast
>
> Treat the object as being the new type without changing the
>bit pattern.

No. You are thinking of reinterpret_cast, but even the reinterpret_cast
might result in a changed size or representation of the value being cast. [5.2.9]

The static_cast is valid if the same conversion could be performed implicitly,
or is one of a set of specified conversions, too long a list for me to copy
here. A static_cast cannot cast away const. [5.2.8]

>
>|> 3) const_cast
>|>
> change the 'const'ness of an object (normally not proper).

I don't know about "normally". Often a non-const object is referred to
via a pointer or reference to const. Casting away the const, which can
be achieved only via const_cast or an old-style cast, is entirely
valid in that case. If an object is declared const, and you try to
assign to that object by casting away const, the results are undefined. [5.2.10]

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: heliotis@xerox.com (Jim Heliotis)
Date: 1995/07/19
Raw View
In article 806053811@nntp.earthlink.net, dqua@earthlink.net (Derick J.R. Qua-Gonzalez) writes:
>Being mostly a C++ "Classic" person (i.e. as defined in the ARM), I have
>only recently started with the ANSI C++ CD (4/95). I am a little confused
>as to the difference and rationale for the existence and purpose of:
>
>1) dynamic_cast
>2) static_cast
>3) const_cast
>
>in light of `plain old' casting.
>
>Can someone please explain this to me? Thank you.
>

Having just recently asked this question myself, and having been given some good
advice to read parts of Stroustrup's _Design_And_Evolution_Of_C++_, I will
express my gratitude by answering this poster's question directly.

dynamic_cast: uses RTTI (run-time type identification) to decide if the cast
  is legal or not. This only works for polymorphic types.
  Common use is downcasting: base --> derived.

static_cast: uses type info known at compile time to decide if the cast is
  legal. If successful, this is still a safe cast. Common uses:
   upcasting
   float <--> int

reinterpret_cast: ignores all type info and simply allows the raw bits to be
  transferred to an object of the destination type. Common uses:
   int <--> pointer
   void * --> ???

const_cast: removes the const'ness or volatile'ness of an expression

So, what do you all think? Did I get it right?

(I still believe this is appropriate for comp.std.c++ because it is such a
 new feature)

============================================================================
Jim Heliotis
Xerox Corporation                                  Voice Phone: 716-383-7383
Mail Stop: 803-01A                                  FAX Phone:  716-383-7395
435 W. Commercial St.                 Electronic Mail: JEH.ROCH803@Xerox.COM
East Rochester, NY 14445
============================================================================







Author: s5vijen@portland.watson.ibm.com (Anil Vijendran)
Date: 1995/07/19
Raw View
>>>>> On 18 Jul 1995 18:50:30 GMT, clamage@Eng.Sun.COM (Steve Clamage) said:

    >> |> 1) dynamic_cast
    >>
    >> A cast which only succeeds if the *true* type of the object is
    >> the type being cast *to*.  This is useful for casting pointers to base
    >> classes into pointers to derived classes in such a way that it only succeeds
    >> if the object really *is* that derived class.

    Steve> No. The cast succeeds if the true type of the object is the target
    Steve> type OR any type derived from that, OR an unambiguous base class of the
    Steve> object type. A dynamic_cast may be applied only to pointers or references,
    Steve> and you cannot cast away "const". [5.2.6]

Does this cover the case where the target type is an unambiguous base
of a type derived from the source type? I don't remember reading about
this anywhere but I have found the necessity to do it once or twice.

For eg:

 class A { };
 class B { };
 class C : public A, public B { };

 void f(A* a)
 {
   B* b = dynamic_cast<B*>(a);
          //...
 }

 void g() { f(new C); }

Thanks for your time.




--
Peace.... +<:-)

Anil
akv@cacs.usl.edu
s5vijen@watson.ibm.com





Author: dqua@earthlink.net (Derick J.R. Qua-Gonzalez)
Date: 1995/07/20
Raw View
Thank you to all who responded to my question. I believe I understand
the concept. Between the helpful replies and a quick trip to BORDERS
Books and Music to look at Dr. Stroustrup's _C++ Programming Language_
(second ed, since I only have the first), all I need now is practice
and more practice. :-)

Best regards,
Derick.
--
+-----------------------------------------------------------------------------+
| Derick R. Qua-Gonzalez                                           | ________ |
| Department of High Energy Physics, California State University   | \      / |
| dqua@Prometheus.EarthLink.Net                                    |  \    /  |
|        ``It is better to be hated for what one is,               |   \  /   |
|          than loved for what one is not.'' (A. Gide)             | G  \/ USA|
+------------------------------------------------------------------+----------+
| mQBNAy/qJJMAAAECANBCB543eTUkdG8Mqx6K2cm3WxCVtKY8ZbB9WY6A2Ne4dQi8 | PGP2.6.2 |
| xh7OxjHXP/eXp5BSbmVAihEGd7r+5g/yknko56kABRG0MERKUiBRdWEtR29uemFs |  Public  |
| ZXogPGRxdWFAUHJvbWV0aGV1cy5FYXJ0aGxpbmsuTmV0Pg==                 | KeyBlock |
| =70DW                                                            | 06.20.95 |
+------------------------------------------------------------------+----------+





Author: herbs@interlog.com (Herb Sutter)
Date: 1995/07/18
Raw View
In article <dqua.806053811@nntp.earthlink.net>,
   dqua@earthlink.net (Derick J.R. Qua-Gonzalez) wrote:
>Being mostly a C++ "Classic" person (i.e. as defined in the ARM), I have
>only recently started with the ANSI C++ CD (4/95). I am a little confused
>as to the difference and rationale for the existence and purpose of:
>
>1) dynamic_cast
>2) static_cast
>3) const_cast

Hey, don't forget reinterpret_cast! :-)

>in light of `plain old' casting.
>
>Can someone please explain this to me? Thank you.
>
>Best regards.

'Plain old casting' isn't very specific about what you're trying to do.
Casting to remove a const, casting to downcast to a subtype pointer, and
casting because you know the exact type even through a base pointer, etc., all
look the same in 'plain old casting' (a menace to you and to those reading
your code).  Changing the definition of a class so that it no longer has a
certain base class will (invisibly!) break casts from derived pointer to base
pointer.  There's more:

See D&E all of section 14.3, particularly 14.3.1.


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Herb Sutter                 2228 Urwin, Ste 102         voice (416) 618-0184
Connected Object Solutions  Oakville ON Canada L6L 2T2    fax (905) 847-6019





Author: swf@ElSegundoCA.ATTGIS.COM (Stan Friesen)
Date: 1995/07/18
Raw View
In article <dqua.806053811@nntp.earthlink.net>, dqua@earthlink.net (Derick J.R. Qua-Gonzalez) writes:
|>... I am a little confused
|> as to the difference and rationale for the existence and purpose of:
|>
|> 1) dynamic_cast

 A cast which only succeeds if the *true* type of the object is
the type being cast *to*.  This is useful for casting pointers to base
classes into pointers to derived classes in such a way that it only succeeds
if the object really *is* that derived class.

|> 2) static_cast

 Treat the object as being the new type without changing the
bit pattern.

|> 3) const_cast
|>
 change the 'const'ness of an object (normally not proper).

--
swf@elsegundoca.attgis.com  sarima@netcom.com

The peace of God be with you.