Xref: utzoo comp.lang.c++:10871 comp.std.c++:502 Path: utzoo!attcan!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!thunder.mcrcim.mcgill.edu!snorkelwacker.mit.edu!bu.edu!att!tut.cis.ohio-state.edu!purdue!decwrl!infopiz!lupine!rfg From: rfg@NCD.COM (Ron Guilmette) Newsgroups: comp.lang.c++,comp.std.c++ Subject: Smart pointers and stupid people (was: garbage collection...) Message-ID: <3071@lupine.NCD.COM> Date: 22 Dec 90 08:07:55 GMT References: <1990Dec20.045909.7681@rice.edu> Followup-To: comp.lang.c++ Organization: Network Computing Devices, Inc., Mt. View, CA Lines: 111 In article 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.