Topic: Checked cast, etc


Author: timh@logcam.co.uk (Tim Hoverd)
Date: 3 Feb 93 10:23:16 GMT
Raw View
A while ago I read a paper (by BS) describing a proposal to put some clever
run-time type information into C++.  The proposal was distinguished by this
rather clever notion of a "checked cast".

Did this proposal ever get submitted to the *the* committee, and if so what
is the status of this area?

Apologies if this is a FAQ.

--------------------------------------------------------------------
Tim Hoverd                                      Logica Cambridge Ltd
              Betjeman House, 104 Hills Road, Cambridge, CB2 1LQ, UK
Internet: timh@logcam.co.uk...CIX: timh.....Compuserve: [71051,2251]




Author: steve@taumet.com (Steve Clamage)
Date: Fri, 5 Feb 1993 00:00:23 GMT
Raw View
timh@logcam.co.uk (Tim Hoverd) writes:

>A while ago I read a paper (by BS) describing a proposal to put some clever
>run-time type information into C++.  The proposal was distinguished by this
>rather clever notion of a "checked cast".

>Did this proposal ever get submitted to the *the* committee, and if so what
>is the status of this area?

The proposal has been classed by the author as "work in progress".

The paper has undergone several revisions, and has been informally
discussed among interested parties.  The paper has not (so far) been
submitted for a vote.
--

Steve Clamage, TauMetric Corp, steve@taumet.com




Author: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Date: 5 Feb 93 16:21:00 GMT
Raw View
In article <timh-030293102312@158.234.41.231> timh@logcam.co.uk (Tim Hoverd) writes:
>A while ago I read a paper (by BS) describing a proposal to put some clever
>run-time type information into C++.  The proposal was distinguished by this
>rather clever notion of a "checked cast".
>
>Did this proposal ever get submitted to the *the* committee, and if so what
>is the status of this area?
>
 The proposal, or something like it, seems certain to
be accepted IMHO.

 Checked casts (dynamic_cast) are not as clever
as you think, however. They are statically but not dynamically
safe: you can get a core dump on a dynamic pointer cast if
you dont check the pointer for 0 correctly, and an exception
for a reference.

 Dynamic_cast was not intended for everyday use and
access to RTTI has been deliberately made difficult and long-winded,
as well as highly restricted.

 There are much better schemes for safer and
more convenient dynamic access, but these are not provided for.
What has been provided is a hack that can be used where such
a hack is mandatory.

 BTW: my comments are based on my own prejudices
and on my interpretation of Bjarnes paper.

--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;------ SCIENTIFIC AND ENGINEERING SOFTWARE ---ph:  2 799 8223 --------




Author: jbn@lulea.trab.se (Johan Bengtsson)
Date: 8 Feb 93 00:14:02 GMT
Raw View
John MAX Skaller (maxtal@extro.ucc.su.OZ.AU) wrote:
: In article <timh-030293102312@158.234.41.231> timh@logcam.co.uk (Tim Hoverd) writes:
: >A while ago I read a paper (by BS) describing a proposal to put some clever
: >run-time type information into C++.  The proposal was distinguished by this
: >rather clever notion of a "checked cast".

:  Checked casts (dynamic_cast) are not as clever
: as you think, however. They are statically but not dynamically
: safe: you can get a core dump on a dynamic pointer cast if
: you dont check the pointer for 0 correctly, and an exception
: for a reference.

Shouldn't an invalid pointer downcast generate an exception too?
It seems quite unnecessary to create yet another difference between
pointers and references.

Suppose you have a function that takes a reference parameter:

void f(some_class& s)
{
   // lots of code...
   dynamic_cast(some_subclass,s).someMethod();  // exception if wrong
}

If you later decide that "s" should be allowed to be NULL, then
you will have to pay attention to the dynamic_casts when changing
the code.

--
--------------------------------------------------------------------------
| Johan Bengtsson, Telia Research AB, Aurorum 6, S-951 75 Lulea, Sweden  |
| Johan.Bengtsson@lulea.trab.se; Voice:(+46)92075471; Fax:(+46)92075490  |
--------------------------------------------------------------------------




Author: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Date: Fri, 12 Feb 1993 16:28:53 GMT
Raw View
In article <5711@holden.lulea.trab.se> jbn@lulea.trab.se (Johan Bengtsson) writes:
>John MAX Skaller (maxtal@extro.ucc.su.OZ.AU) wrote:
>: In article <timh-030293102312@158.234.41.231> timh@logcam.co.uk (Tim Hoverd) writes:
>: >A while ago I read a paper (by BS) describing a proposal to put some clever
>: >run-time type information into C++.  The proposal was distinguished by this
>: >rather clever notion of a "checked cast".
>
>:  Checked casts (dynamic_cast) are not as clever
>: as you think, however. They are statically but not dynamically
>: safe: you can get a core dump on a dynamic pointer cast if
>: you dont check the pointer for 0 correctly, and an exception
>: for a reference.
>
>Shouldn't an invalid pointer downcast generate an exception too?
>It seems quite unnecessary to create yet another difference between
>pointers and references.

 A basic technique with pointers would be to have
an if-then-else chain of tests. There is consideration
of a language extension to allow declarations in
'if' and 'while' statements too:

 if(X* x=dynamic_cast<X*>pObj){ ... }
 else if(Y* y=dynamic_cast<Y*>pObj{ ...}
 ...

>
>Suppose you have a function that takes a reference parameter:
>
>void f(some_class& s)
>{
>   // lots of code...
>   dynamic_cast(some_subclass,s).someMethod();  // exception if wrong
>}
>
>If you later decide that "s" should be allowed to be NULL, then
>you will have to pay attention to the dynamic_casts when changing
>the code.

 Well, 's' is a reference so its not really suppose to be 'NULL'
as a pointer can be (although this is actually a not the case :-)


--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;------ SCIENTIFIC AND ENGINEERING SOFTWARE ---ph:  2 799 8223 --------




Author: jbn@lulea.trab.se (Johan Bengtsson)
Date: 15 Feb 93 15:27:15 GMT
Raw View
John MAX Skaller (maxtal@extro.ucc.su.OZ.AU) wrote:
: In article <5711@holden.lulea.trab.se> jbn@lulea.trab.se (Johan Bengtsson) writes:
: >John MAX Skaller (maxtal@extro.ucc.su.OZ.AU) wrote:
: >: In article <timh-030293102312@158.234.41.231> timh@logcam.co.uk (Tim Hoverd) writes:
: >: >A while ago I read a paper (by BS) describing a proposal to put some clever
: >: >run-time type information into C++.
: >
: >:  Checked casts (dynamic_cast) are not as clever
: >: as you think, however. They are statically but not dynamically
: >: safe: you can get a core dump on a dynamic pointer cast if
: >: you dont check the pointer for 0 correctly, and an exception
: >: for a reference.
: >
: >Shouldn't an invalid pointer downcast generate an exception too?
: >It seems quite unnecessary to create yet another difference between
: >pointers and references.

:  A basic technique with pointers would be to have
: an if-then-else chain of tests. There is consideration
: of a language extension to allow declarations in
: 'if' and 'while' statements too:

:  if(X* x=dynamic_cast<X*>pObj){ ... }
:  else if(Y* y=dynamic_cast<Y*>pObj{ ...}
:  ...

==> I think there should be a seperate mechanism for type tests,
 perhaps dynamic_isa(type,ptr).  Having pointers and references
 behave similar should be more important.  Optimizing the
 dynamic_cast for type tests IMHO makes pointer casts more error
 prone.

: >Suppose you have a function that takes a reference parameter:
: >
: >void f(some_class& s)
: >{
: >   // lots of code...
: >   dynamic_cast(some_subclass,s).someMethod();  // exception if wrong
: >}
: >
: >If you later decide that "s" should be allowed to be NULL, then
: >you will have to pay attention to the dynamic_casts when changing
: >the code.

:  Well, 's' is a reference so its not really suppose to be 'NULL'
: as a pointer can be (although this is actually a not the case :-).

==> Yes, but the decision s!=NULL may change, forcing a move to pointer
 representation.  Other cases can easily be constructed where a
 reference must be changed to a pointer.  There is also the mental
 burden of memorizing yet another differene between pointers and
 references.




Author: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Date: Tue, 16 Feb 1993 13:19:28 GMT
Raw View
In article <5765@holden.lulea.trab.se> jbn@lulea.trab.se (Johan Bengtsson) writes:
>John MAX Skaller (maxtal@extro.ucc.su.OZ.AU) wrote:
>
>:  if(X* x=dynamic_cast<X*>pObj){ ... }
>:  else if(Y* y=dynamic_cast<Y*>pObj{ ...}
>:  ...
>
>==> I think there should be a seperate mechanism for type tests,
> perhaps dynamic_isa(type,ptr).  Having pointers and references
> behave similar should be more important.  Optimizing the
> dynamic_cast for type tests IMHO makes pointer casts more error
> prone.

 IF we wanted to support dynamic downcasting (and I dont particularly
*at this stage*), I suspect type checks are not the way to go,
because the check is separated from the cast and so is error
prone. Can I suggest:

 class A { ...

 typeof(pObj)
 {
  type(Y* y) { ... }
  type(X* x) { ... }
  type(A* a) { /* default, always matches! */ }
 }

The 'type' things are to be considered exactly like function
calls. In particular, if the exact type of pObj was derived
from Y, then the Y* would still match.

 Normal overloading rules would apply in matching the
exact type to the supplied set of functions. A natural extension
of this is to allow multiple arguments:

 typeof(pObj1, pObj2)
 {
  type(X* x1, X* x2) { ... }
  type(X* x1, Y* y2) { ...}
 }

which is a sort of poor mans multiple dispatcher.

Note that THIS syntax supports reference just fine:

 typeof(Obj)
 {
  type(X& x) { ...}
  type(Y& y) { ...}
 }

However, there is some justification in NOT providing such a
convenient mechanism. It would be too easy to abuse.
Hence the 'dynamic_cast' mechanism, which is not intended
to support Smalltalk style codes, as the 'typeof .. type'
construct outlined above would be.

I dont like downcasting EVEN if its hidden by nice syntax as above.

(These ideas came from my study of variants and discriminated unions.
The principal difference is the for variants there is a guarrantee
of completeness. In the RTTI case, that can be obtained
perhaps by supplying or omitting the static type of the
candidate object (which always matches as a last resort,
or always causes an exception if a type which cannot
be handled is encountered )

--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;------ SCIENTIFIC AND ENGINEERING SOFTWARE ---ph:  2 799 8223 --------