Topic: Automatic Instance Counting
Author: Petter Urkedal <petter@matfys.lth.se>
Date: 1998/05/20 Raw View
James Kuyper wrote:
> An invasive smart pointer is one that cannot be implemented for
> arbitrary objects, but only for objects of classes that contain certain
> specific members, which were added specifically to permit the smart
> pointer to work properly. Those are the 'invasions' that make it an
> 'invasive' smart pointer.
I'll reflect further on that... Now that we have templates and
member-templates, we can write
template <class T> class container
{ int ic; T obj; /* constructors as below */ };
template <class T> class instance {
container<T>* ptr;
public:
template <class T1> instance(T1 x1)
: ptr(new container<T>(x1)) {}
template <class T2, class T3> instance(T1 x1, T2 x2)
: ptr(new container<T>(x1, x2)) {}
// ... constructors up to a certain number of arguments
};
which makes an on-the-fly-invation, or that is: no invation. But
if we want to refer to a base-class, we must eighter (1) provide
the complete type, as in
instance<base_type, complete_type>
(2) use invasive smart-references, or (3) use two-component pointers,
as James Kanze explains (not cited).
It is also possible within the Draft to decide whether a template
class parameter inherits a particular base class. Thus, it is
possible to provide solutions (2) and (3) with the same interface:
instance<type>
--> invasive_instance<type>, if type inherits instance_base
--> pointer_dyad_kind_of_instance<type>, otherwise
(We'll tell the user that things goes faster if he inherits
polymorphic classes as `virtual public instance_base')
According to my experience, when not using virtual functions, it
does not matter to parametrize algorithms with an extra type:
template <class T> some_algorithm(instance<some_type, T>);
On the other hand, this solution does not mix well with virtual
functions, as their utility is precisely to hide the types.
> There's a lot of neat, efficient tricks you
> can pull with invasive smart pointers, that you can't do with
> non-invasive ones.
Does anyone know any on-line articles, or such?
Petter.
--
[- http://matfys.lth.se/~petter/ -]
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Petter Urkedal <petter@matfys.lth.se>
Date: 1998/05/18 Raw View
James Kuyper wrote:
> An invasive smart pointer is one that cannot be implemented for
> arbitrary objects, but only for objects of classes that contain certain
> specific members, which were added specifically to permit the smart
> pointer to work properly. Those are the 'invasions' that make it an
> 'invasive' smart pointer.
I'll reflect a bit further on that... Now that we have templates and
member-templates, we can write
template <class T> class container
{ int ic; T obj; /* constructors as below */ };
template <class T> class instance {
container<T>* ptr;
public:
template <class T1> instance(T1 x1)
: ptr(new container<T>(x1)) {}
template <class T2, class T3> instance(T1 x1, T2 x2)
: ptr(new container<T>(x1, x2)) {}
// ... constructors up to a certain number of arguments
};
which makes an on-the-fly-invation, or that is: no invation. But
if we want to refer to a base-class, we must eighter (1) provide
the complete type, as in
instance<base_type, complete_type>
(2) use invasive smart-references, or (3) use two-component pointers,
as James Kanze explains (not cited).
It is also possible within the Draft to decide whether a template
class parameter inherits a particular base class. Thus, it is
possible to provide solutions (2) and (3) with the same interface:
instance<type>
--> invasive_instance<type>, if type inherits instance_base
--> pointer_dyad_kind_of_instance<type>, otherwise
(We'll tell the user that things goes faster if he inherits
polymorphic classes as `virtual public instance_base')
According to my experience, when not using virtual functions, it
does not matter to parametrize algorithms with an extra type:
template <class T> some_algorithm(instance<some_type, T>);
On the other hand, this solution does not mix well with virtual
functions, as their utility is precisely to hide the types.
> There's a lot of neat, efficient tricks you
> can pull with invasive smart pointers, that you can't do with
> non-invasive ones.
Does anyone know any on-line articles, or such?
Petter.
--
[- http://matfys.lth.se/~petter/ -]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1998/05/13 Raw View
Petter Urkedal wrote:
>
> jkanze@otelo.ibmmail.com wrote:
>
> > Petter Urkedal <petter@matfys.lth.se> wrote:
...
> > I think that the real problem with reference counting in the committee
> > was getting a consensus. Invasive reference counting can be as fast,
> > or even faster, than auto_ptr, but it imposes significant restraints
> > on what can be pointed to. Non invasive reference counting imposes
> > a two word smart pointer; regardless of other costs, this may mean the
> > difference between the generated code returning the pointer in a
> > register, and returning it in memory.
>
> Sure, we don't want something that interferes with the efficiency. (I'm
> not sure if I understand what you mean be `invasive' here, but a assume
An invasive smart pointer is one that cannot be implemented for
arbitrary objects, but only for objects of classes that contain certain
specific members, which were added specifically to permit the smart
pointer to work properly. Those are the 'invasions' that make it an
'invasive' smart pointer. There's a lot of neat, efficient tricks you
can pull with invasive smart pointers, that you can't do with
non-invasive ones.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Petter Urkedal <petter@matfys.lth.se>
Date: 1998/05/08 Raw View
jkanze@otelo.ibmmail.com wrote:
> Petter Urkedal <petter@matfys.lth.se> wrote:
>
> > 2. I do not understand the exclution of reference counting from
> > the standard on the basis that it is inefficient.
> > [see http://reality.sgi.com/austern_mti/std-c++/faq.html]
> > The efficiency can be assured by providing the user with the opportunity
> >
> > * to access objects without checking the ownership, whenever he knows
> > that the current context has exclusive ownership. When NDEBUG
> > is not defined, the implementation will check the ownership anyway
> > and produce a runtime error in case the integrity is violated.
> >
> > * to release an object to another context, with no implied reference
> > counting.
> >
> > Am I wrong about this?
>
> Yes. This helps in certain situations, by allowing the user to forgo
> the reference counting. But the whole idea of smart pointers is that
> the user doesn't forgo it.
I agree that reference counting is inefficient if used as a general
scheme,
just to provide easy memory management. Still, reference counting is
important in some cases (i.e. when manipulating symbolic expressions).
The idea is to have standardized interface to smart pointers/references
such that the implementation may be improved without changing the code
using it. Specifically, we may say something like
template <class T>
my_string<T> : public instance< my_string_data<T> > {
T operator[](int i) const { return to_const()[i]; }
T& operator[](int i) { modify(); return to_mutable()[i]; }
// etc.
// to_const(), modify() and to_mutable() provied by
instance<...>
}
or whatever the interface is. Even if an extensive interface requires
the user to do much of the work, a library provides a finished
*debugged*
and optimized (or will-become-optimized) solution, which gives clear
runtime errors when the program is ill-formed according to the
specification of the smart pointers/references. (Which is much better
than knowing that there is memory leak *somewhere*.)
> I think that the real problem with reference counting in the committee
> was getting a consensus. Invasive reference counting can be as fast,
> or even faster, than auto_ptr, but it imposes significant restraints
> on what can be pointed to. Non invasive reference counting imposes
> a two word smart pointer; regardless of other costs, this may mean the
> difference between the generated code returning the pointer in a
> register, and returning it in memory.
Sure, we don't want something that interferes with the efficiency. (I'm
not sure if I understand what you mean be `invasive' here, but a assume
it refers to the logic and syntax of the smart pointers `invading' the
code. If this is a techical term i would appreciate a definition or
reference.)
SIDENOTE: I do see a difficulty in supporting extensive C++
type-conversions between smart pointers, without copying the referenced
object. (And since abstract base classes cannot be copied, this problem
must be solved.) Since the reference counters are located relative to
the most derived type (or the full allocated block of memory), a smart
reference to a base class which does not know the complete type, cannot
access it. Two-pointer sized smart pointers are one solution. Another
solution requires the user to derive all classes from a virtual base
class, which interfers with efficiency, as well as the independence
between modules. I know no solutions to this.
> > 3. When I do not know whether a template class parameter has explicit
> > or implicit conversion from another type, I need to overload both
> > conversions in my class:
> >
> > template <class T>
> > class instance {
> > T *p;
> > template <class U> explicit instance(const instance<U>& x)
> > { p =U*)x.p; }
> > template <class U> instance(const instance<U>& x)
> > { p =.p; }
> > };
> >
> > This doesn't work on my compiler (egcs), and I could not find an answer
> > in the Draft. Is this valid code? Why not?
>
> No. In fact, it is hard to see what it should mean. Explicit says that
> there is no implicit conversion using this constructor -- in this case,
> the first constructor says that there is no implicit conversion of
> instance<U> to instance<T>, and the second constructor says that there
> is one.
>
> What are you trying to overload on?
First a typo: The first constructor should read
template <class U> explicit instance(const instance<U>& x)
{ p =(T*)x.p; } // (U*) replaced by (T*)
I'm sorry if this caused any confusion.
The functionality of the class is as follows:
* If the an explicit conversion from an instance<U> to an instance<T>
is performed, the explicit construtor's body will be used, applying
the expression
p=(T*)x.p
Thus, if U* is only explicitely convertible to T* (like if U is a
base class of T), there will be no warnings from the compiler.
* However, if an implicit conversion from instance<U> to instance<T>
is
performed, the compiler produces warnings or errors unless U* is
*implicitly* convertible to T* (like if T is a base class of U).
Thus, we emulate the type-conversion rules of the template parameters,
and
get proper error messages when converting implicitely from a base class
to a derived class.
Regards,
Petter.
[- http://matfys.lth.se/~petter/ -]
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Petter Urkedal <petter@matfys.lth.se>
Date: 1998/04/23 Raw View
1. The problem of ownership is raised before. The auto_ptr in the
standard library is useful, but does not solve the real problem.
To those interested in automatic instance counting, I have an
implementation of a reference-like class (public domain) avaliable at
http://matfys.lth.se/~petter/src/mmt/mmt.html
To catch your interest, it works with incomplete types, abstract
base-classes, elementary types, supports arrays, and supports
non-copying type-conversions. (That's it for the ad!)
The work is in progress. I post this message here IN HOPE TO RECEIVE
COMMENTS before I decide the final implementation and make bigger
attemts to publish it. If you try it, does it compile at all on your
platform and compiler? (It requires template members, that I know!)
Bugs? Suggestions on the implementation? Thanks.
2. I do not understand the exclution of reference counting from
the standard on the basis that it is inefficient.
[see http://reality.sgi.com/austern_mti/std-c++/faq.html]
The efficiency can be assured by providing the user with the opportunity
* to access objects without checking the ownership, whenever he knows
that the current context has exclusive ownership. When NDEBUG
is not defined, the implementation will check the ownership anyway
and produce a runtime error in case the integrity is violated.
* to release an object to another context, with no implied reference
counting.
Am I wrong about this?
- - -
In implementing the "ownership-managed referencces", the following
questions on the Standard arised:
3. When I do not know whether a template class parameter has explicit
or implicit conversion from another type, I need to overload both
conversions in my class:
template <class T>
class instance {
T *p;
template <class U> explicit instance(const instance<U>& x)
{ p = (U*)x.p; }
template <class U> instance(const instance<U>& x)
{ p = x.p; }
};
This doesn't work on my compiler (egcs), and I could not find an answer
in the Draft. Is this valid code? Why not?
4. My interpretation of logic_error is radical: Any program which
throws a logic_error is ill-formed. Thus, when the program is bug-free
and NDEBUG is defined, all code with the sole purpose of throwing a
logic_error may be taken away for optimalization. I.e.
#ifndef NDEBUG
if(...) throw logic_error(...);
#endif
Code that depends on catching logic_error other than for debugging is
thus ill-formed. It this interpretation sensible?
Best regards,
Petter Urkedal
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jkanze@otelo.ibmmail.com
Date: 1998/04/24 Raw View
In article <353E2185.5DEC9737@matfys.lth.se>#1/1,
Petter Urkedal <petter@matfys.lth.se> wrote:
> 2. I do not understand the exclution of reference counting from
> the standard on the basis that it is inefficient.
> [see http://reality.sgi.com/austern_mti/std-c++/faq.html]
> The efficiency can be assured by providing the user with the opportunity
>
> * to access objects without checking the ownership, whenever he knows
> that the current context has exclusive ownership. When NDEBUG
> is not defined, the implementation will check the ownership anyway
> and produce a runtime error in case the integrity is violated.
>
> * to release an object to another context, with no implied reference
> counting.
>
> Am I wrong about this?
Yes. This helps in certain situations, by allowing the user to forgo
the reference counting. But the whole idea of smart pointers is that
the user doesn't forgo it.
I think that the real problem with reference counting in the committee
was getting a consensus. Invasive reference counting can be as fast,
or even faster, than auto_ptr, but it imposes significant restraints
on what can be pointed to. Non invasive reference counting imposes
a two word smart pointer; regardless of other costs, this may mean the
difference between the generated code returning the pointer in a
register, and returning it in memory.
> - - -
>
> In implementing the "ownership-managed referencces", the following
> questions on the Standard arised:
>
> 3. When I do not know whether a template class parameter has explicit
> or implicit conversion from another type, I need to overload both
> conversions in my class:
>
> template <class T>
> class instance {
> T *p;
> template <class U> explicit instance(const instance<U>& x)
> { p = (U*)x.p; }
> template <class U> instance(const instance<U>& x)
> { p = x.p; }
> };
>
> This doesn't work on my compiler (egcs), and I could not find an answer
> in the Draft. Is this valid code? Why not?
No. In fact, it is hard to see what it should mean. Explicit says that
there is no implicit conversion using this constructor -- in this case,
the first constructor says that there is no implicit conversion of
instance<U> to instance<T>, and the second constructor says that there
is one.
What are you trying to overload on?
--
James Kanze +33 (0)1 39 23 84 71 mailto: kanze@gabi-soft.fr
+49 (0)69 66 45 33 10 mailto: jkanze@otelo.ibmmail.com
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
Conseils en informatique orient=E9e objet --
-- Beratung in objektorientierter Datenverarbeitung
----- Posted via Deja News, The Leader in Internet Discussion
-----
http://www.dejanews.com/ Now offering spam-free web-based newsreading
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Daniel Parker" <danielp@nospam.com>
Date: 1998/04/24 Raw View
Petter Urkedal wrote in message <353E2185.5DEC9737@matfys.lth.se>...
>2. I do not understand the exclution of reference counting from
>the standard on the basis that it is inefficient.
>[see http://reality.sgi.com/austern_mti/std-c++/faq.html]
Well, some of the classes in the standard library are implemented with
reference counting, notably the string classes. And there are some vexing
problems with this in a multi-threaded environment, see the SGI cite for
more details. In a particular context, reference counting can work very,
very well, but I don't think anyone has a perfect reference counting
solution that is not exposed in some way when there are multiple threads.
That need not matter to you or I, but it would certainly matter to the
standards body; they would probably hesitate to approve a reference counting
class which could not in all circumstances be declared safe.
--
Regards,
Daniel Parker danielp@no_spam.anabasis.com.
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html ]