🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.std.c++
Article #47

Re: run-time type checking (was: Re: Covariant Types in Derived Classes)

#47
From: David (Lujun) Shang
Date: Fri, 31 Jul 1992 23:01
109 lines
5270 bytes
In article <1992Jul30.172830.18501@ucc.su.OZ.AU> maxtal@extro.ucc.su.OZ.AU  
(John MAX Skaller) writes:
> 	I refered to compiler generated RTTI. User generated RTTI
> must obey the current restrictions of C++, and so is as sound and safe
> as C++ currently is. I also refered to a specific case in one place,
> and say in general in another, intending to say 'always'. OK?
> 
I cannot understand why user generated RTTI is sound and safe while the  
compiler generated RTTI is not.

> > 
> >> Actually, I think downcasting is OK when you already knew what the
> >> type was, or could have. Then it is just a convenience. And safe.
> >> 
> >Then we have not disagreement any more.
> 
> 	Well, I'm not sure about that. We certainly dont have a
> specific *agreement* about when downcasting is sound and when
> it is not, nor how to suitably constrain it. 
>
If you think "downcasting is OK when you already knew what the type is", then  
we have no disagreement. I said from the begining that the downcast should only  
be allowed when you already know that the cast is on the exact type you want.  
How do you know within a polymorphic behavior? Just by explicit run time type  
check. The compiler will *enforce* you to do so in order to produce the safe  
code. If you perform a downcast which you are not sure of the type within the  
context, the compiler does not know either, then the compiler will not let your  
program pass.

> 	I am looking at a constraint where all the things that
> a function can downcast to must be listed (or implied by the list)
> in the interface.
> 
> 	f(Base[Derived1,Derived2]*);
> 
> 	This mechanism has some nice features, although I am
> not sure about its soundness yet.
>
Are Derived1 and Derived2 sealed classes? Or is it true that the pointer  
"Base[Derived1,Derived2]*" can only accept exactly two derived classes ( no  
derived classes of Derived1 or Derived2)? IF NOT, such constraint helps nothing  
in RTTI and downcast. Let me suppose YES, it still helps little (see below)
 
> 	Member functions can always downcast to their class.
> That immediately implies a 'thisclass' facility, and with no
> additional syntax in the declaration. 
>
It is never a necissity to downcast "this" to its own class! "thisclass" is not  
used to specify "this", it's a kind of garbage to say that "this cat is a cat".  
"thisclass" is used to specify other object (input of the member function) that  
is of the same type of this object. Member function CANNOT downcast its input  
to its class without care if the input is not specified by "thisclass".
  
> 	Furthermore, explicit downcasting operators are not 
> required always, since the declaration already lists the legal
> downcasts.
>
True, but not by your reason. Example,

    Animal a1 = new Cat;
    Animal a2 = new Dog;
    Cat c = *a1;
    Dog *d = a2;

No explicit RTTC required here. Both you and the complier know these downcasts  
are correct and safe;

You proposed a constraint through a fixed set of *exact* types (I suppose so).  
What is the purpose of such contraint? It cannot eliminates or even reducing  
the necessity of run time type check. Non-derterminisim between the two and  
among the infinitive both require run time type check. 

When I refer to a fixed set of "exact types", I usually use them to make the  
interface more precise. But additional RTTC is needed when you pass a less  
constrained argument to this interface.

> 	Even better, the syntax might support casting to unrelated
> types, and can be implemented then, and when no virtual functions
> are available, by using tagged pointers or some other mechanism.
>
A complete RTTI should already support casting from a set of unrealted types to  
a concrete type. It has nothing to do with any constraint.

> 	Finally, for the moment, one can implement
> 
> 	f(Base[Derived1, Derived2]* b)
> 	{
> 		...
> 		type switch(ab) {
> 		case Derived1:
> 			b->Derived1_member();
> 		case Derived2:
> 			b->Derived2_member();
> 		default:
> 			b->Base_member();
> 		};
> 	}
> 
> although there would have to be an implied break after each case.

No default case needed here in the type switch because the interface of "f"  
already tells you that there are only two cases of the input type. This is the  
reason we need constraint: to help the resulting implementation more correct.  
While "thiscalss" describes a covariant constraint of dependent types, tagged  
union types (what you proposed is actually a kind of tagged union type as far  
as I can understand) desribes a constraint of independent types. They cannot be  
replaced with each other.

David Shang
Technical Details
Message-ID: <1992Jul31.230135.1201@cadsun.corp.mot.com>
Path: arc1-ca.pugleaf.net!sparky!uunet!ftpbox!motsrd!news
References: <1992Jul30.172830.18501@ucc.su.OZ.AU>

Show Full Headers
Complete Article Headers
Newsgroups: comp.std.c++,comp.lang.c++
Path: arc1-ca.pugleaf.net!sparky!uunet!ftpbox!motsrd!news
From: shang@corp.mot.com (David (Lujun) Shang)
Subject: Re: run-time type checking (was: Re: Covariant Types in Derived Classes)
Message-ID: <1992Jul31.230135.1201@cadsun.corp.mot.com>
Sender: news@cadsun.corp.mot.com
Reply-To: shang@corp.mot.com
Organization: Motorola, Inc., Software Research and Development, Rolling Meadows, IL. 60008
References: <1992Jul30.172830.18501@ucc.su.OZ.AU>
Date: Fri, 31 Jul 92 23:01:35 GMT
Lines: 112