Topic: Smart pointers that behave like real pointer in C++ are possible
Author: kennedy@intellection.com (Brian M Kennedy)
Date: Fri, 4 Jun 1993 22:16:20 GMT Raw View
In article <1993Jun4.042126.7166@cdf.toronto.edu> g2devi@cdf.toronto.edu (Deviasse Robert N.) writes:
> In spite of the common perception to the contrary, it *is* possible to
> implement type-safe, efficient, easy to use smart pointers that behave
> very similarly to regular pointers.
^^^^ ^^^^^^^^^
I'm not sure how to respond to this. I don't think it is a common perception
that it is not possible to implement smart pointers that are _similar_ to
regular pointers. I know of several examples that would fit that.
However, it is a common perception that it is not possible to implement smart
pointers that are the _same_ as regular pointers; and thus, it is not possible
to implement smart pointers that are a superset of regular pointers (the
typical desire).
You said "very similarly" -- which is subject to interpretation. But per
mine, I would consider no smart pointer implementation to date to fit that.
And the technique you present is actually _less_similar_ to regular pointers
than several known techniques.
Anyone interested in this topic should read "Smart Pointers: They're Smart,
But They're Not Pointers" by Daniel Edelson in the 1992 USENIX C++ Conference
Proceedings. In that paper, Daniel does a good job of describing the various
ways different smart pointers fail to emulate regular pointers. He discusses
and compares 6 smart pointer designs, all of which are (IMO) superior to the
one proposed here (but, the choice depends upon the situation).
> [..design omitted..]
>
> As the you can see, the above scheme follows the sematics of smart pointers
> very closely and is efficient and type-safe. There are 3 problems with the
> above scheme though:
... and more:
(4) The scheme uses user-defined conversions (via constructors) to
effect hierarchical conversions. However, that is not the same
as a hierarchical conversion. Why? Because only _one_ user-defined
conversion will be used implicitly. So, if you have a user-defined
conversion from a Foo to a DBCA*, then you can pass a Foo to the
function test2(A*). In contrast, a conversion from Foo to DBCA_ptr
will not allow passing a Foo to the function test2(A_ptr), because
two user-defined conversions would be required.
(5) Hierarchical preference is not maintained. Consider an additional
class EBA. If test2 is overloaded to take an A_ptr or a BA_ptr, then
a call to test2 from an EBA_ptr is ambiguous. In contrast, with
regular pointers, the depth in the hierarchy will be used to resolve
the overloading (selecting test2(BA*)). (See attached code if you did
not follow that -- you cannot replace the regular pointers with the
proposed smart pointers -- the last test2 call will be ambiguous.)
Coupled with your problem number 3, this design is actually quite far from regular
pointers. Combine that with the cumbersome-ness of problem 1, and they are
not very desirable.
> Case 3 may be easily be solved via templates. The following demonstrates:
No, it is not the same. Const conversion via user-defined conversions is only
half-way to a regular const conversion. Why? Because it consumes that _one_
user-defined conversion that will be used implicitly. This is the same
argument as #4 above.
> It solves *all* problems with
> smart pointers mentioned in "Smart Pointers: They're Smart, but They're Not
> Pointers", except the memory leakage problem mentioned in section 2.5.
Huh? Both problems 4 and 5 I mention above are described in Daniel's paper,
and your design fails both. I suggest you read again more carefully and
perhaps code up and exercise some of Daniel's examples.
== Brian M Kennedy <kennedy@intellection.com> ==
== Intellection, Inc. =========================
// Example of hierarchical preference in regular pointers.
// It can be emulated by smart pointers, but not without other problems.
#include <iostream.h>
// ... Given this class hierachy
struct A { A(){} };
struct BA : public A { BA(){} };
struct EBA : public BA { EBA(){} };
void test2(A*) { cout << "A*" << endl; }
void test2(BA*) { cout << "BA*" << endl; }
int main()
{ A* a_ptr = new A;
BA* ba_ptr = new BA;
EBA* eba_ptr = new EBA;
// Tests to ensure that these smart pointers allow the automatic
// conversions: Derived* to Base* with no ambiguities.
test2(a_ptr);
test2(ba_ptr);
test2(eba_ptr);
return 0;
}
===
The output:
[art:tests] CC sptr.c
[art:tests] a.out
A*
BA*
BA*
Author: g2devi@cdf.toronto.edu (Deviasse Robert N.)
Date: Sat, 5 Jun 1993 07:08:00 GMT Raw View
In article <KENNEDY.93Jun4161620@art.intellection.com> kennedy@intellection.com (Brian M Kennedy) writes:
>In article <1993Jun4.042126.7166@cdf.toronto.edu> g2devi@cdf.toronto.edu (Deviasse Robert N.) writes:
>
>> In spite of the common perception to the contrary, it *is* possible to
>> implement type-safe, efficient, easy to use smart pointers that behave
>> very similarly to regular pointers.
> ^^^^ ^^^^^^^^^
>
>I'm not sure how to respond to this. I don't think it is a common perception
>that it is not possible to implement smart pointers that are _similar_ to
>regular pointers. I know of several examples that would fit that.
>
>However, it is a common perception that it is not possible to implement smart
>pointers that are the _same_ as regular pointers; and thus, it is not possible
>to implement smart pointers that are a superset of regular pointers (the
>typical desire).
>
>You said "very similarly" -- which is subject to interpretation. But per
>mine, I would consider no smart pointer implementation to date to fit that.
>And the technique you present is actually _less_similar_ to regular pointers
>than several known techniques.
>
Sorry, I retract my claim.
I was working on another idea that did have a lot of promise but was less
trivial (as you might expect) and required more specification. While doing
the specification amd testing the idea I came across the above idea. I ran
a few tests, got excited at the potential and simplicity of the idea, and
posted it. I'm usually a lot more methodical in my testing and a lot more
careful about what I post. The artical has been cancelled.
BTW, I still think that it is possible to define an extension that will allow
smart pointers to have a superset of the properties of real pointers. My
previous idea does seem to have this property (it involves allowing certain
conversions to chain exactly 2 levels but only under certain restrictive
conditions) -- but don't worry, I won't post that one until I'm absolutely
sure that it actually does have those properties (i.e. a few months from now).
If possible, I'll try and implement some form of a preprocessor to test out
the idea.
--
/----------------------------------+------------------------------------------\
| Robert N. Deviasse |"If we have to re-invent the wheel, |
| EMAIL: g2devi@cdf.utoronto.ca | can we at least make it round this time"|
+----------------------------------+------------------------------------------/