From: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Subject: Re: Type System
Organization: MAXTAL P/L C/- University Computing Centre, Sydney
Date: Sun, 10 Jan 1993 16:27:57 GMT

In article <1993Jan9.001948.28388@lucid.com> jss@lucid.com (Jerry Schwarz) writes:
>In article <C0Iy9o.9x@frumious.uucp>, pat@frumious.uucp (Patrick Smith) writes:
>|> There is another loophole. :-(
>|> But it's (I hope) an unusual type of situation. :-)

	Special case of a more general problem?

>|> 
>|>    struct A { A(); /*...*/ };
>|>    A* pa;
>|>    A::A { pa = this; }
>|> 
>|>    void f() {
>|>       const A a;
>|>       // Now pa has non-const type but points to an immutable object.
>|>    }

	LOVELY! Who needs ~const?  Who needs cast away const either?

	struct A { A*me; A() : me(this) {} 
		int i;
		f()const; 
	}

	A::f()const { .... 	
		me->i=1; // fooled ya!
	};

>
>You're right.  I knew about that loophole, but forgot about it when
>I posted my original item.  If anyone has ideas for a clean way
>to close this loophole, I'd be interested to hear them.  

	Do we want to close it?
>
>The problem is that the object is only "marked" immutable when the
>constructor returns.  The constructor itself is supposed to be free
>to modify the object in any way it chooses.

	The problem is that the object is *never* marked const.
What is made const is the 'reference' or pointer to the object.

	If we had 'const' constructors we could at least
distinguish whether a const object was being constructed or not.
Please take below with salt (LOTS):

	You could close the loophole by disallowing any use
of 'this' :-)

	This also stops the constructor creating another
object and passing it the non-const this.

	I'm not sure if the loophole matters though. The 
const mechanism is an aid only. It totally fails to 
handle 'delegation': it is a well known trick for cache
support etc:

	class X { int i; .. };
	class H { X* p; H() p(new X){}};
	const H h; // nothing can help us: the constructor of H
		   // doesnt know its const
		  // so it cant create a 'const' X object

	h.p->i=2; // modified the 'object'

To get around this

	class constH {const X* p; constH() : p(new const X){}};
	constH h;
	h.p->i=1; //error

which means whenever you want to support 'const' and 'delegation'
like this you have to create two 'handle' classes : a const one,
and a non-const one. (This doesnt close the loophole, just
lets you create const objects that *subsequently* cant
be modified).

I'm not sure even having 'const' constructors would help here.
(Set a switch?)

Now: the loophole is just a special case of this in which
the pointer *happens* to refer to the object itself.

So it isnt a loophole unless the delegation thing above
is also. The user code is just delegating control to itself :-)

Moral: there's no loophole: your notion that there exist
const objects is faulty. Only references and pointers
to objects can be 'const'. Its up to the constructor
to determine if it wants to give certain objects
non-const access to the object by passing them
the 'this' pointer.

General public access is still restricted as intended.
Priviledged access is still available to those
trusted objects that the constructor deems to
grant non-const priviledge to (including the object
itself --- as a special case).

Now consider a REAL const object:

	rom X x;

Thats really in ROM. Now: the constructor had better
NOT modify the object: its REALLY immutable!

-- 
;----------------------------------------------------------------------
        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.std.c,comp.std.internat,comp.lang.c