Topic: strict" mode for C++0x - a problem


Author: transwarpt@aol.com (TransWarpT)
Date: Thu, 16 Aug 2001 16:28:45 GMT
Raw View
Assuming an intrusive smart pointer, the object being pointed to can override
operator& to return a new smart pointer. Which would force all pointers to the
object to be smart pointers.

"Capp, Mike" <Mike.Capp@tfeurope.com> wrote:

>Is that necessarily true, or realistic? All the smart pointers I've seen
>supply operator*, and I don't know of any way to prevent clients from using
>&(*mysmartptr) if they want to badly enough. Okay, it's bordering on fraud,
>but they'll do it.
>

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: kanze@gabi-soft.de (James Kanze)
Date: 16 Aug 2001 15:49:26 -0400
Raw View
Ross Smith <ross.s@ihug.co.nz> wrote in message
news:<3B79A503.9669067@ihug.co.nz>...
> James Kanze wrote:

> > Ross Smith <ross.s@ihug.co.nz> wrote in message
> > news:<3B60A6B0.2B74EDE6@ihug.co.nz>...
> > > John Nagle wrote:

> > > >     (The problem being discussed is "how, in a
> > > > reference-counted environment, do you get a smart pointer to
> > > > an object from within one of its own methods?"  If we are to
> > > > have safe reference counts, that's a necessary operation.)

> > > Why? I can't imagine any circumstances where an object needs
> > > control over its own lifetime within its own functions, unless
> > > you want to sanction the equivalent of "delete this".

I missed the last sentence earlier.  It sort of surprises me; I'd say
that delete this is probably the most frequent way model objects are
deleted.  (The object receives a message that what it is modeling no
longer existes, so it deletes itself.)

> > It's not rare for an object to want to return a pointer to itself.
> > And one of the basic rules for making smart pointers 100% safe is
> > that all of the pointer to the object must be smart pointers.

> But the question wasn't about smart pointers in general, it was
> specifically about reference counted pointers. I gather you're
> referring to a system that would have a special non-owning pointer
> class for this purpose, which (I'm guessing) would differ from
> ordinary pointers only in not supporting deletion. The purpose of
> reference counting is control over lifetime, and I still say there's
> no case where an object should handle that itself.

I believe that an important part of John's safe C++ is that no one
acquires a raw pointer, for any reason.  That means that when an
object must create a new object which refers to it (say for a
callback), it must be able to pass some form of a smart pointer to
that new object.  I agree that most of the time, the new object will
not share ownership, and so needs a pointer which will be null'ed, or
some such, when the initial object is deleted.  But I can also imagine
cases where the new object does share ownership; in such cases, the
orginal object must be able to convert this to shared ownership
pointer.

--
James Kanze                                   mailto:kanze@gabi-soft.de
Beratung in objektorientierer Datenverarbeitung --
                             -- Conseils en informatique orientie objet
Ziegelh|ttenweg 17a, 60598 Frankfurt, Germany, Til.: +49 (0)69 19 86 27
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: 17 Aug 01 07:15:17 GMT
Raw View
In article <3b794a21$1@primark.com>, Capp, Mike <Mike.Capp@tfeurope.com>
writes
>Is that necessarily true, or realistic? All the smart pointers I've seen
>supply operator*, and I don't know of any way to prevent clients from using
>&(*mysmartptr) if they want to badly enough. Okay, it's bordering on fraud,
>but they'll do it.

It is also absolutely necessary if I need to use a function that takes a
raw pointer. Such things are sometimes outside the programmers control.


Francis Glassborow      ACCU
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]




Author: John Nagle <nagle@animats.com>
Date: 17 Aug 2001 16:00:35 GMT
Raw View
James Kanze wrote:
>
> John Nagle <nagle@animats.com> wrote in message
> news:<3B5B4A60.DC1C790E@animats.com>...
> > The problem:
> >     When control is in an object method of an object managed with
> > nonintrusive smart pointers, there's no way to get a smart pointer.
> > All you have is "this", and you can't make a smart pointer from
> > "this" because you have no way to find out where the reference
> > counts live.  If you want to create something that points back to
> > the current object, the proper mechanism would be a weak smart
> > pointer.  But the object method doesn't have sufficient information
> > to make make one to itself.
>
> What about "safe" non-intrusive pointers?  These maintain a mapping
> pointer->counter in a map (or a hash_map).  When creating a new smart
> pointer from a raw pointer, the raw pointer is looked up in the map.
> The existing counter is used if it is found; otherwise, a new one is
> introduced.
>
> Note that this isn't necessarily as expensive as it seems.  In
> practice, the map is only accessed when converting a raw pointer to a
> smart pointer, and when the reference count hits zero.

    That would work.  I'd thought of that,  but it seemed too much
machinery to put in at a relatively low level.  Basically, this
says that for each type, there's a dictionary of all the instances.
That seems alien to C++.

    It's an intriguing idea, though.   If you have such dictionaries,
non-conservative GC is possible.  So are some other interesting
operations.  But it seems to me to be a concept for a higher-level
language than C++.

    I'd given that idea some thought in a different context - weak
pointers.  If you have a lookup system, weak pointers can be
implemented through it, and you don't need weak reference counts.
Again, though, it seems too much hidden machinery for C++.

     John Nagle
     Animats

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: kanze@gabi-soft.de (James Kanze)
Date: 17 Aug 2001 16:00:36 GMT
Raw View
"Carl Daniel" <carl@pixami.com> wrote in message
news:<9lefon$p6s@dispatch.concentric.net>...

> I'd go so far as to say that any reference counting system which
> does not use an embedded reference count (either explitictly
> embedded, as in most COM programming, or implicitly provided by the
> allocator) will have some serious problems with object lifetime
> management.  That's the one reason I'll never use
> boost::shared_ptr<>.

There's nothing to prevent the boost::shared_ptr from maintaining a
map of object pointers to counters.  (That said, I also prefer
invasive pointers.  But more than a preference for invasive pointers,
I prefer using pseudo-standards.  So I use booch:shared_ptr in all new
developments.)

--
James Kanze                                   mailto:kanze@gabi-soft.de
Beratung in objektorientierer Datenverarbeitung --
                             -- Conseils en informatique orient   e objet
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany, T   l.: +49 (0)69 19 86 27

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Carl Daniel" <carl@pixami.com>
Date: 17 Aug 2001 22:24:20 GMT
Raw View

"James Kanze" <kanze@gabi-soft.de> wrote in message
news:d6651fb6.0108170707.6169e439@posting.google.com...
>
> "Carl Daniel" <carl@pixami.com> wrote in message
> news:<9lefon$p6s@dispatch.concentric.net>...
>
> > I'd go so far as to say that any reference counting system which
> > does not use an embedded reference count (either explitictly
> > embedded, as in most COM programming, or implicitly provided by the
> > allocator) will have some serious problems with object lifetime
> > management.  That's the one reason I'll never use
> > boost::shared_ptr<>.
>
> There's nothing to prevent the boost::shared_ptr from maintaining a
> map of object pointers to counters.  (That said, I also prefer
> invasive pointers.  But more than a preference for invasive pointers,
> I prefer using pseudo-standards.  So I use booch:shared_ptr in all new
> developments.)
>

True - nothing prevents boost::shared_ptr from doing that... but it doesn't.
I agree with John Nagle (see other post, this thread) that that's too much
machinery at a low level.  I'd much rather see a "standard" (ISO or
otherwise) that says that operator new allocates space for a reference count
with each allocation, along with a "standard" way to convert a
pointer-to-object to a pointer-to-reference count (but not the reverse of
that).  Preferably that way would be "fast", e.g. pointer math, but an
implementation which uses a map would also satisfy the semantics.  I suppose
that'd interact badly with user-defined operator-new, however...

-cd





      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: brangdon@cix.co.uk (Dave Harris)
Date: 19 Aug 2001 22:30:45 GMT
Raw View
carl@pixami.com (Carl Daniel) wrote (abridged):
> I'd much rather see a "standard" (ISO or otherwise) that says
> that operator new allocates space for a reference count with each
> allocation, along with a "standard" way to convert a pointer-to-object
> to a pointer-to-reference count (but not the reverse of that).

I'd rather it didn't. The memory would be wasted for implementations which
provided full garbage collection. It would also be wasted for applications
which did their own reference counting, or didn't use RC/GC at all. I
don't think the standard should mandate any particular RC/GC strategy.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: kanze@gabi-soft.de (James Kanze)
Date: 14 Aug 2001 10:10:40 -0400
Raw View
John Nagle <nagle@animats.com> wrote in message
news:<3B5B4A60.DC1C790E@animats.com>...

>      There are two basic ways to do "smart pointers", "intrusive",
> where the reference counts are part of the object, and
> "nonintrusive", where they're somewhere else, typically a separate
> object pointed to by all the smart pointers pointed at a given
> object.  Nonintrusive smart pointers seem to be preferred, as they
> impact existing programs less.  Intrusive smart pointers usually
> require inheriting everything from some common base class, which is
> unpopular in C++.

> The problem:
>     When control is in an object method of an object managed with
> nonintrusive smart pointers, there's no way to get a smart pointer.
> All you have is "this", and you can't make a smart pointer from
> "this" because you have no way to find out where the reference
> counts live.  If you want to create something that points back to
> the current object, the proper mechanism would be a weak smart
> pointer.  But the object method doesn't have sufficient information
> to make make one to itself.

What about "safe" non-intrusive pointers?  These maintain a mapping
pointer->counter in a map (or a hash_map).  When creating a new smart
pointer from a raw pointer, the raw pointer is looked up in the map.
The existing counter is used if it is found; otherwise, a new one is
introduced.

Note that this isn't necessarily as expensive as it seems.  In
practice, the map is only accessed when converting a raw pointer to a
smart pointer, and when the reference count hits zero.

--
James Kanze                                   mailto:kanze@gabi-soft.de
Beratung in objektorientierer Datenverarbeitung --
                             -- Conseils en informatique orientie objet
Ziegelh|ttenweg 17a, 60598 Frankfurt, Germany, Til.: +49 (0)69 19 86 27
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: kanze@gabi-soft.de (James Kanze)
Date: 14 Aug 2001 10:11:57 -0400
Raw View
Ross Smith <ross.s@ihug.co.nz> wrote in message
news:<3B60A6B0.2B74EDE6@ihug.co.nz>...
> John Nagle wrote:

> >     (The problem being discussed is "how, in a reference-counted
> > environment, do you get a smart pointer to an object from within
> > one of its own methods?"  If we are to have safe reference counts,
> > that's a necessary operation.)

> Why? I can't imagine any circumstances where an object needs control
> over its own lifetime within its own functions, unless you want to
> sanction the equivalent of "delete this".

It's not rare for an object to want to return a pointer to itself.
And one of the basic rules for making smart pointers 100% safe is that
all of the pointer to the object must be smart pointers.

--
James Kanze                                   mailto:kanze@gabi-soft.de
Beratung in objektorientierer Datenverarbeitung --
                             -- Conseils en informatique orientie objet
Ziegelh|ttenweg 17a, 60598 Frankfurt, Germany, Til.: +49 (0)69 19 86 27
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: remove.haberg@matematik.su.se (Hans Aberg)
Date: 15 Aug 01 13:36:25 GMT
Raw View
John Nagle wrote:

>     (The problem being discussed is "how, in a reference-counted
> environment, do you get a smart pointer to an object from within
> one of its own methods?"  If we are to have safe reference counts,
> that's a necessary operation.)

Ross Smith <ross.s@ihug.co.nz> wrote in message
news:<3B60A6B0.2B74EDE6@ihug.co.nz>...

> Why? I can't imagine any circumstances where an object needs control
> over its own lifetime within its own functions, unless you want to
> sanction the equivalent of "delete this".

In article <d6651fb6.0108130757.2b6fdaa7@posting.google.com>,
kanze@gabi-soft.de (James Kanze) wrote:
>It's not rare for an object to want to return a pointer to itself.
>And one of the basic rules for making smart pointers 100% safe is that
>all of the pointer to the object must be smart pointers.

Starting with the last comment, yes, indeed, it is important not only that
an object always can hand over a reference to itself, but in addition,
when working with a polymorphic variable, it is often important that an
object can self-mutate to an object of a different type.

The way I solved this, when working with a ref count, is to use a handle:
  class object_root {
    object_handle* this_; // pointer to handle
    ...
  };

  class object_handle {
    mutable size_t count_; // ref count.
    object_root* data_; // allocated data common to the reference cluster
    ...
  };

  class object {
    object_handle* handle_; // pointer to handle ref cluster
    ...
  };

If one wants to add polymorphic data, one derives from the object_root
class, but otherwise one the user would only use the object class.

Here, the handles are non-movable data, but as all are of the same size,
one can find fast allocations for them (using say singly linked lists).
Using functional language lingo, the construction above is the "boxed"
version; if one puts data into the handle class objects, they become
"unboxed". But then this data cannot be moved in memory. And all handles
become bigger. But the payoff is speed for small data.

The construction above does not have anything particular with ref counts
to do: One could just as well use a conservative GC. I think that the C++
language should support that, so that one does not have to fiddle around
with ref counts unless it is absolutely needed for some reason.

  Hans Aberg      * Anti-spam: remove "remove." from email address.
                  * Email: Hans Aberg <remove.haberg@member.ams.org>
                  * Home Page: <http://www.matematik.su.se/~haberg/>
                  * AMS member listing: <http://www.ams.org/cml/>

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]




Author: Ross Smith <ross.s@ihug.co.nz>
Date: 15 Aug 01 13:40:22 GMT
Raw View
James Kanze wrote:
>
> Ross Smith <ross.s@ihug.co.nz> wrote in message
> news:<3B60A6B0.2B74EDE6@ihug.co.nz>...
> > John Nagle wrote:
>
> > >     (The problem being discussed is "how, in a reference-counted
> > > environment, do you get a smart pointer to an object from within
> > > one of its own methods?"  If we are to have safe reference counts,
> > > that's a necessary operation.)
>
> > Why? I can't imagine any circumstances where an object needs control
> > over its own lifetime within its own functions, unless you want to
> > sanction the equivalent of "delete this".
>
> It's not rare for an object to want to return a pointer to itself.
> And one of the basic rules for making smart pointers 100% safe is that
> all of the pointer to the object must be smart pointers.

But the question wasn't about smart pointers in general, it was
specifically about reference counted pointers. I gather you're referring
to a system that would have a special non-owning pointer class for this
purpose, which (I'm guessing) would differ from ordinary pointers only
in not supporting deletion. The purpose of reference counting is control
over lifetime, and I still say there's no case where an object should
handle that itself.

--
Ross Smith <ross.s@ihug.co.nz> The Internet Group, Auckland, New Zealand
========================================================================
"Unix has always lurked provocatively in the background of the operating
system wars, like the Russian Army."                  -- Neal Stephenson

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]




Author: "Capp, Mike" <Mike.Capp@tfeurope.com>
Date: 15 Aug 2001 20:06:39 -0400
Raw View
"James Kanze" <kanze@gabi-soft.de> wrote

> And one of the basic rules for making smart pointers 100% safe is that
> all of the pointer to the object must be smart pointers.

Is that necessarily true, or realistic? All the smart pointers I've seen
supply operator*, and I don't know of any way to prevent clients from using
&(*mysmartptr) if they want to badly enough. Okay, it's bordering on fraud,
but they'll do it.

There are at least two interpretations of "safe" that could apply here. If
you mean "there can never be dangling pointers of any kind" then yes, we
need to do everything we can to discourage clients from getting their hands
on raw pointers. However, this is asking a lot, and (IMHO) isn't generally
expected. The STL defines any number of situations in which iterators can be
rendered invalid, which I'd have thought was analogous.

A more realistic interpretation would be "there can never be dangling SMART
pointers". In this case, we can safely mix smart and raw pointers IF all
objects being referenced have protected virtual destructors (and a common
base class with an appropriate friend decl), so that they can't be deleted
via a raw pointer. In practice, if you can enforce this, you can probably
enforce intrusive reference counting as well, which makes it trivial to get
a smart pointer from a raw one. No good for large existing projects,
granted, but quite attractive for new ones.

- Mike




"This communication is intended solely for the addressee and is confidential and not for third party unauthorised distribution."
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Carl Daniel" <carl@pixami.com>
Date: 16 Aug 2001 08:47:44 -0400
Raw View
"Ross Smith" <ross.s@ihug.co.nz> wrote in message
news:3B79A503.9669067@ihug.co.nz...
> James Kanze wrote:
> >
> > Ross Smith <ross.s@ihug.co.nz> wrote in message
> > news:<3B60A6B0.2B74EDE6@ihug.co.nz>...
> > > John Nagle wrote:
> >
> > > >     (The problem being discussed is "how, in a reference-counted
> > > > environment, do you get a smart pointer to an object from within
> > > > one of its own methods?"  If we are to have safe reference counts,
> > > > that's a necessary operation.)
> >
> > > Why? I can't imagine any circumstances where an object needs control
> > > over its own lifetime within its own functions, unless you want to
> > > sanction the equivalent of "delete this".
> >
> > It's not rare for an object to want to return a pointer to itself.
> > And one of the basic rules for making smart pointers 100% safe is that
> > all of the pointer to the object must be smart pointers.
>
> But the question wasn't about smart pointers in general, it was
> specifically about reference counted pointers. I gather you're referring
> to a system that would have a special non-owning pointer class for this
> purpose, which (I'm guessing) would differ from ordinary pointers only
> in not supporting deletion. The purpose of reference counting is control
> over lifetime, and I still say there's no case where an object should
> handle that itself.
>

This is a very commonn (in fact, de-facto) circumstance in C++ COM
programming.  Objects return interface pointers to clients in reponse to
requests.  It's essential that an object be able to return a new "owning"
smart pointer to itself to a client to maintain the level of implementation
freedom which exists today: Today's version of a member function might
return a new reference to the object on which it was called, while
tomorrow's version returns a reference to a new "helper" object created just
for that client (*).  With normal COM semantics, the client can't tell the
difference since it always gets an "owning" pointer to the object given it.

I'd go so far as to say that any reference counting system which does not
use an embedded reference count (either explitictly embedded, as in most COM
programming, or implicitly provided by the allocator) will have some serious
problems with object lifetime management.  That's the one reason I'll never
use boost::shared_ptr<>.

-cd

(*) In Don Box terminology, these are referred to as "Tear-Off Interfaces",
and are very handy for interfaces which are rarely requested and expensive
to implement.  The basic object leaves the interface unimplemented, but
instantiates a helper object (the "tear off") in response to a request for
the interface.
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Carl Daniel" <carl@pixami.com>
Date: 23 Aug 2001 22:02:20 GMT
Raw View

"Dave Harris" <brangdon@cix.co.uk> wrote in message
news:memo.20010819181717.9551J@brangdon.madasafish.com...
>
> carl@pixami.com (Carl Daniel) wrote (abridged):
> > I'd much rather see a "standard" (ISO or otherwise) that says
> > that operator new allocates space for a reference count with each
> > allocation, along with a "standard" way to convert a pointer-to-object
> > to a pointer-to-reference count (but not the reverse of that).
>
> I'd rather it didn't. The memory would be wasted for implementations which
> provided full garbage collection. It would also be wasted for applications
> which did their own reference counting, or didn't use RC/GC at all. I
> don't think the standard should mandate any particular RC/GC strategy.
>

Just to be clear: this is in the context of "strict mode" C++ (a
hypothetical system) which, as defined by John Nagle, uses some sort of
Smart Pointers for owning pointers and doesn't use GC.  If and only if
that's the case would I favor the implicit allocation (embedding) of a
reference count.    I certainly didn't intend for the statement above to
mean that I advocate all C++ compilers always doing that!

-cd




      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Ross Smith <ross.s@ihug.co.nz>
Date: 27 Jul 01 13:02:58 GMT
Raw View
John Nagle wrote:
>
>     (The problem being discussed is "how, in a reference-counted
> environment, do you get a smart pointer to an object from within
> one of its own methods?"  If we are to have safe reference counts,
> that's a necessary operation.)

Why? I can't imagine any circumstances where an object needs control
over its own lifetime within its own functions, unless you want to
sanction the equivalent of "delete this".

--
Ross Smith <ross.s@ihug.co.nz> The Internet Group, Auckland, New Zealand
========================================================================
"Unix has always lurked provocatively in the background of the operating
system wars, like the Russian Army."                  -- Neal Stephenson

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]




Author: brangdon@cix.co.uk (Dave Harris)
Date: 27 Jul 2001 14:17:52 -0400
Raw View
nagle@animats.com (John Nagle) wrote (abridged):
>     When control is in an object method of an object managed
> with nonintrusive smart pointers, there's no way to get a
> smart pointer.  All you have is "this", and you can't make
> a smart pointer from "this" because you have no way to find
> out where the reference counts live.

If the object is creating smart pointers to itself, it clearly knows about
smart pointers - they have already intruded. So using an intrusive smart
pointer surely adds no extra burden.


> Nonintrusive smart pointers seem to be preferred, as they
> impact existing programs less.

In particular, they are the only way to fly with types like "int", and
with classes which are not aware they are being smart-pointed to. They are
necessary for any general solution. If classes *are* aware, then intrusive
pointers are preferred because they are more efficient. They involve fewer
memory allocations and indirections.


> Intrusive smart pointers usually require inheriting everything
> from some common base class, which is unpopular in C++.

That's another way of saying the class must be aware of what's going on.
It's not a new problem as such. It's an argument against requiring
intrusive pointers, but not against supporting them.

Think about it another way... suppose we have two independent
non-intrusive smart pointer classes, both pointing to the same object.
Each will have its own separate counter. It will be chaos; it won't work.
Instead, we need all the smart pointers to a given object to cooperate.
Thus for each object, we want a rule which says which smart pointer to
use. We need this rule even if smart pointers are not intrusive.

It sounds to me like we need both kinds of pointer - intrusive and
non-intrusive. Non-intrusive for types which don't know about strict mode
and therefore don't need to create smart pointers to themselves. Intrusive
for types which do know about strict mode, and need to create pointers to
themselves and/or desire the extra efficiency.

We don't want to bother clients about this. We want to be able to say
ptr<T> and get the right kind of pointer - intrusive, or one of several
possible flavours of non-intrusive - appropriate for T. Partial
specialisation of ptr<> should do the trick.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: "Capp, Mike" <Mike.Capp@tfeurope.com>
Date: 25 Jul 01 21:33:27 GMT
Raw View
No, aside from the truly revolting solutions (e.g. an
ObjectAddess->RefCounter map) I don't think there's a way out of this one.

I use a mixture of intrusive smart pointers (usually as data members, for
lifetime management) and raw pointers (for local-scoped stuff, parameter
passing etc). Having raw pointers is nice because you avoid the refcounting
overhead when passing/assigning - nobody wants to write myFunction(const
MySmartPointer<MyClass>&) - and being able to create a smart pointer from
such a raw pointer or reference is essential.

I'm very disappointed that Boost doesn't support any form of intrusive smart
pointer. I'd love to break out of not-invented-here-land and make more use
of standard libraries, but in this case the cost is far too great. Sure,
intrusive pointers don't make much sense for existing large projects, but
that's no reason to deny their use for new or smaller projects

Mike Capp




"This communication is intended solely for the addressee and is confidential and not for third party unauthorised distribution."

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]




Author: John Nagle <nagle@animats.com>
Date: 26 Jul 2001 09:35:24 -0400
Raw View
"Capp, Mike" wrote:
>
> No, aside from the truly revolting solutions (e.g. an
> ObjectAddess->RefCounter map) I don't think there's a way out of
> this one.

    (The problem being discussed is "how, in a reference-counted
environment, do you get a smart pointer to an object from within
one of its own methods?"  If we are to have safe reference counts,
that's a necessary operation.)

    One way out, when you can't inherit from some intrusive
smart pointer class, is to have a data member that consists of a weak
pointer to oneself.   That's ugly, but it's a way out when you
don't control the base class.

> I use a mixture of intrusive smart pointers (usually as data members, for
> lifetime management) and raw pointers (for local-scoped stuff, parameter
> passing etc). Having raw pointers is nice because you avoid the refcounting
> overhead when passing/assigning

     Yes.  Basically, all this "auto scope" stuff is about allowing
you to do that, but with compile time checking to make it safe.

>  nobody wants to write myFunction(const
> MySmartPointer<MyClass>&) - and being able to create a smart pointer
> from such a raw pointer or reference is essential.

     And that's what you can't do with nonintrusive smart pointers,
because you can't find the reference count cell from a raw pointer.

     No obvious good solutions suggest themselves.  But
let's think about it for a few days.

> I'm very disappointed that Boost doesn't support any form of intrusive
> smart pointer.

     There are a few intrusive smart pointer template libraries
around, although Boost doesn't seem to have one.

     John Nagle
     Animats
---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: John Nagle <nagle@animats.com>
Date: 25 Jul 2001 05:36:54 GMT
Raw View
    Here's a problem with "strict mode", or more specifically
"auto scope", as I've discussed it.  This is actually a general
problem with smart pointers, so it's probably been addressed.
But I don't have a good answer today, and I'd appreciate any
insights.

Ref: http://www.animats.com/papers/languages/index.html

Background:

     There are two basic ways to do "smart pointers",
"intrusive", where the reference counts are part of the object,
and "nonintrusive", where they're somewhere else, typically
a separate object pointed to by all the smart pointers
pointed at a given object.  Nonintrusive smart pointers
seem to be preferred, as they impact existing programs less.
Intrusive smart pointers usually require inheriting everything
from some common base class, which is unpopular in C++.

The problem:
    When control is in an object method of an object managed
with nonintrusive smart pointers, there's no way to get a
smart pointer.  All you have is "this", and you can't make
a smart pointer from "this" because you have no way to find
out where the reference counts live.  If you want to
create something that points back to the current object,
the proper mechanism would be a weak smart pointer.
But the object method doesn't have sufficient information
to make make one to itself.

    Sometimes, programmers cheat on the smart pointer
system to get around this problem, using raw pointers
for backpointers.  But with my "auto scope" proposal,
"this" has to be "auto" scope, which is safe but
prevents that cheat.

    The obvious solutions are ugly.  Requiring intrusive
smart pointers has high impact on existing code.
Allowing raw pointers intermixed with smart pointers
is unsafe.   Any good ideas?

     John Nagle
     Animats



      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]