Topic: Smart pointers and stupid people (was: garbage collection...)


Author: rfg@NCD.COM (Ron Guilmette)
Date: 22 Dec 90 08:07:55 GMT
Raw View
In article <CLINE.90Dec21171912@cheetah.ece.clarkson.edu> cline@sun.soe.clarkson.edu (Marshall Cline) writes:
>
>So the basic problem is that C++ pointers aren't ``smart'' enough.  Ie:
>a copy-collect GC routine moves objects, and the pointers are machine
>addresses rather than some higher level `logical' pointers, so the
>machine addresses become invalid.
>
>A possible solution is to ban `Cons*' and replace it with ConsPtr,
>which is a smart pointer...

Great!  Now how do I "ban" the use of the type Cons* ???

Marshall's idea of "banning" the use of regular pointers is good one
except for one thing.  The C++ language (as currently defined) does
not provide any form of support for "banning" the use of specific
pointer types.

This notion of banning pointers to "managed" or "controlled" classes
seems to be the general answer for a lot of the questions which arise
when `smart pointers' are used.  It seems that `smart pointers' work
wonderfully, but only so long as nobody on your project team forgets
what's going on and then (accidently) codes up a declaration for a T*
object rather than a smart_pointer_to_T object.

Of course we could even deal with *those* cases if we were allowed
to overload such things as operator= for T*'s, but we can't because
the language rules say that we can't.  (The justification for this
is a bit esoteric, and has to do with language mutability. But I digress...)

Anyway, given that we can't defend ourselves (e.g. by overloading
operator= for pointer types) from the random dummies who may happen
to get assigned to our project teams at any given instant in time,
wouldn't it be nice if (as an alternative) we could have some way
of instructing the compiler to absolutely "ban" people from declaring
objects of type T* for cases where we want Ts to be accessed only
via values of some `smart_pointer_to_T' type?

Rather than inventing yet another keyword (banned?) how about something
like this:

 class T;

 class smart_pointer_to_T {
  /* ... magical stuff, possibly including ref counts, etc. */
  class T* pointer;
 public:
  smart_pointer_to_T ();
  smart_pointer_to_T& operator= (smart_pointer_to_T);
  T& operator * ();
 };

 protected class T {
  /* ... innards of T ... */
 };

The idea here is that once we declare `class T' to be `protected', then
from that point forward (in the compilation) it becomes impossible to
use the type T* in any way, shape, or form.  In particular, it would
be impossible to declare objects to be of type T* or objects of type T**,
or objects of type T*[] or anthing like that.  It would also become
illegal to cast anything to (T*) or (T**) or (T*[]) or (T*&) or anything
like that.  Furthermore, it would be impossible to use, or even to
generate values of type T*.

Assume for the moment that C++ already included the concept of "protected"
classes (as described herein).  Looking in my crystal ball, I see one
very curious side-effect of making a given class "protected". Consider:

 class T T_array[10];

 ... T_array[i] ... // ERROR: value of type T* generated/used

The indicated line would contain an error because in C and C++ any
reference to an array element gets converted (internally in the compiler)
to it's simpler equivalent.  For an array reference like `a[i]' the
compiler effectively converts this to `*(a+i)' where the evaluation
of the sub-expression `a' yields a pointer to the first element of
the array `a'.

I'm not at all sure whether this curious side-effect of declaring a class
to be "protected" would be good or bad in practice.  I can see where
it might at first seem to be an irritant, but I have a funny feeling
that it would end up *aiding* in the enforcement of the programmer's wish
to insure that all accesses to type T object go (indirectly) through
some object of type `smart_pointer_to_T'.

In summary, I have believed for quite some time that the concept of
`smart pointers' is a terrific one, but that C++ desperately needs
some way to ENFORCE their universal use for certain "controlled"
types.  I believe that allowing classes to be declared as "protected"
could be a good way to provide such enforcement because it should be
relatively simple to implement in actual C++ compilers.  After all,
it involves no new keywords and no new run-time semantics.  All it does
is to provide the programmer with a convenient way to tell the compiler
to treat a slightly larger class of things as compile-time errors.

I welcome discussion of the idea of "protected" classes.  If people
have no objection to the idea, I may just decide to ask x3j16 to
consider it.  I'd like to get some feedback first however.

P.S.  When I spoke earlier about "random dummies" getting assigned to
project teams, I was definitely *NOT* refering to anybody here at NCD.
We don't have any dummies here at all... random or otherwise.  Everybody
I work with here is incredibly bright. Unfortunately, I cannot say the
same thing about *all* of the places that I have worked over the years. :-(

--

// Ron Guilmette  -  C++ Entomologist
// Internet: rfg@ncd.com      uucp: ...uunet!lupine!rfg
// Motto:  If it sticks, force it.  If it breaks, it needed replacing anyway.