From: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Newsgroups: comp.lang.c++,comp.std.c++
Subject: Re: run-time type checking (was: Re: Covariant Types in Derived Classes)
Date: 30 Jul 92 17:28:30 GMT
Organization: MAXTAL P/L C/- University Computing Centre, Sydney

In article <1992Jul29.162440.21848@cadsun.corp.mot.com> shang@corp.mot.com writes:
>In article <1992Jul28.210755.3548@ucc.su.OZ.AU> maxtal@extro.ucc.su.OZ.AU (John  
>MAX Skaller) writes:
>> >
>> >> NOW: I want to demonstrate why using RTTI is WRONG in this case,
>> >> and why the Species() function is required.	
>> >>
>> >Remenber, your function Species() IS JUST FOR THE PURPOSE TO PROVIDE RTTI. 
>> 
>> 	Yes. I'm not against having run-time-type information
>> available. 
>
>See your original statement -- what you want to demonstrate.

	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?

>
>> >> 
>> >> The demonstration is so simple, and applies so generally, I wonder
>> >> why I didnt think of it before.
>> >> 
>> >> 	class DOG : Animal { ....
>> >> 	class HUND : Animal { .. // german programmer
>> >> 
>> >This is never an execuse. If it is, your Species() function has the same  
>> >problem:
>> >
>> > 	char* DOG::Species()
>> >        { return "DOG"; }
>> > 	char* DOG::Species()
>> >        { return "HOUND"; }   // german programmer
>> 
>> 	What?? The compiler catches this error: it is a duplicate
>> definition.
>>
>The class DOG can be declared as static in different modules and it is highly  
>possible if an Australian and a German work for the same project that is  
>separated into many different modules.

	Sorry. The linker catches the error, not the compiler.

> 
>> 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.

	My efforts at the moment are directed to preserving the
mechanism suggested for Bjarne's proposal, that is, using
a downcasting of pointers, getting 0 if the wrong type
is there (and exceptions to references).

	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.

	Member functions can always downcast to their class.
That immediately implies a 'thisclass' facility, and with no
additional syntax in the declaration. 

	Furthermore, explicit downcasting operators are not 
required always, since the declaration already lists the legal
downcasts.

	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.

	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.
-- 
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
	Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;--------------- SCIENTIFIC AND ENGINEERING SOFTWARE ------------------
Newsgroups: comp.lang.c++,comp.std.c++