From: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Subject: Re: Downcasting (was: Re: run-time type checking)
Organization: MAXTAL P/L C/- University Computing Centre, Sydney
Date: Fri, 21 Aug 1992 00:40:33 GMT

In article <4847@holden.lulea.trab.se> jbn@lulea.trab.se (Johan Bengtsson) writes:
>: In a statically secure system, I argue that it is important to access
>: an object only by its explicitly declared accessible interface.
>
>****	I think _that_ is the issue.  I'd say a system can be statically
>	secure, even if it does (undeclared) runtime-checked down-casts
>	(that is, if the program only does the down-casts when possible).

	You may be right, I certainly dont have a more convincing argument
than the example I gave before:

	class X { 
	protected: 
		int i;
	public: 
		int get()const {return i;}
		X(int j) : i(j) {}
	};

	class Y : public virtual X {
	public: 
		Y(int j) : X(j) {}
		void set(int j) { i=j;}
	};

	f(X&);
	Y aY;
	f(Y);

I am disturbed by the fact that f can modify its X object when the
interface says it cant. 

>	I think we agree on the need to sometimes do controlled downcasts.
	
	Dont know what you mean by 'sometimes'. I propose no
downcasting, ever. Ban even existing legal downcasts. I know this
is overly restrictive, but any loosening of the restriction I would
accept without further involved argument cannot do what the
downcasting advocates want---to downcast to a class without
explicit interface modification is necessary for extensibility.

	The issue then is whether there is a price to pay for the
extensibility or not. I argue there is, although I could be wrong.
To convince me you have to assert that nothing valuable is lost
in the case given above. In that case, the assumption I could make
that Y.i remains constant over the call to f is violated if
downcasting is allowed. At least there is a lost optimisation
opportunity. At worst all of polymorphism is destroyed.
>
>	I also admit that when you see a need for a downcast, you should
>	ask yourself why you have lost track of the type of the object,
>	and change the code to avoid it, if possible.  Downcasting is a
>	last resort.  Yes, I use GOTOs too (in the form of break/continue
>	statements).

	Downcasting is an ABUSE of the concept of polymorphism,
it tries to mix up the ideas of polymorphism with heterogeneity.
These are totally different mechanisms conceptually that unfortunately
both can be implemented using inheritance.

>
>	You may argue that the system is easier to _maintain_ by making the
>	possible down-casts visible in the base class, and I would agree.

	No, I argue that to mix polymorphism and heteromorphism
in inheritance, you need to distinguish which 'bits' are poly
morphic and which are hetero-morphic.

	I see the problem is that because you can add arbitrary
derived classes polymorphically people assume they can arbitrary
classes heterogeneically too. This is false IMHO. Heteromorphic
extensions are always finite and non-arbitrary (there is a specific
number of them, and you need to handle all the cases separately,
i.e., you need a compile time 'switch'.) But polymorphism 
handles infinite (arbitrary) cases by using indirection,
i.e. vectoring. Here the address is not known, but the address
of the address is. The actual function is not known, but 
the addresses of all the functions ARE known.

	A switch does not and cannot have this property.
The fact that downcasting requires

	a) Run-time type info
	b) Compile time explicit case codes to be written

the most dynmaic and most static of concepts togther, seems to say
something is inappropriate. Mm.

	Lets have a look at this:

	void (*f)(X&); // function pointer
	...
	f(x);		// vectored call

This is statically typesafe and works for ARBITRARY functions
that might be assigned to f. The price one pays for the ARBITRARYness
is that ALL the functions you can assign to f MUST have the same
interface.

	Now:

	switch (...)
	case ..:  f(1);
	case ..: f('m',2.1);
	...

Here there is a fixed list of cases, and the f's are unrelated 
except by name. They are quite specific f's, and take different
parameters. Also type safe.

Now the downcasters want to do BOTH the above simultaneously,
to have type safe arbitrary switching/vectoring, and I dont
believe its possible.

>
>: >
>: >	The importance is that in neither case do you have to
>: >	intervene with the source or compiled code of the base
>: >	class to do what you want.  This is considered good
>: >	for behaviour (overriding virtuals), so why not also
>: >	for interfaces (unrestricted but safe downcasting)?
>: 
>: 	It is sound for virtuals because they are declared!
>
>****	But not in the base class!  You can't find out which
>	derived classes override a virtual by inspecting the
>	base class.

	Of course not. You dont CARE how or whether the derived class
defines the virtual. Indeed you MUSTNT KNOW. And you dont NEED to know.
That lack of knowledge is power. Only by denying all knowledge
can you claim arbitrariness, and only with arbitrariness do you
have openness.
>
>: >	A base class intended for future inheritance (even by
>: >	other programmers) should support overriding behaviour
>: >	using virtual member functions, and should support
>: >	interface extension by runtime-checked, safe downcasting.
>: >
>: >	This lessens the risk that future users without access to the
>: >	source code will get stuck when deriving from the base class.
>: 
>: The point of polymorphism is that
>: your should not rely on derived class behaviour in routines
>: given a base object, and you shouldn't need to.
>
>****	But you do, since any derived class may have an
>	incorrect implementation of a virtual method.
>
	Yes, but that is another issue. In principle
there are invariants etc, and you shouldnt violate them
even if the language can't check them.

	You MUST rely on the implementor of a derived class
not violating the semantics of the base class, because there is
no other option. You cant check the semantics of an arbitrary
and not yet written derived class in the base class completely,
although invariants might help narrow the illegal
cases down.

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