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"|
+----------------------------------+------------------------------------------/