Topic: auto_ptr efficiency (was: Construct final in exception handling...)


Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/11/13
Raw View
paul.black@vf.vodafone.co.uk writes:

>nicolas (n.) chapados <chapados@nortel.ca> wrote:
>> Fergus Henderson wrote:
>>
>> > the new [auto_ptr] design contains both a pointer and a bool to indicate
>> > ownership.  There are additional time and space costs to manipulate
>> > this bool.
>>
>> On most platforms that have word-alignment restrictions for dynamic
>> allocation, this will be a non-issue: since you're guaranteed that the
>> lower 2 bits (for a 32-bit machine) of your pointer will be zero, just
>> encode the bool there.
>
>I couldn't find that guarantee in the draft standard.

No, but nicolas (n.) chapados <chapados@nortel.ca> didn't claim that
this optimization was valid on all platforms, just on most platforms.
It's OK for the implementation of auto_ptr to be non-portable.

However, the implementation of auto_ptr must work even for classes
with user-defined new operators, or if the user redefines the global
operator new.  To deal with that, it must address the issues you
point out below:

>Also, if the class has very simple attributes (e.g. all chars) then
>class new & delete operators might not (and do not need to) provide a
>block of memory with the same alignment properties as the global
>operators.

One way of dealing with this is by using template specialization
to only do this optimization if the size of the object is one
for which there is a type of that size that requires at least
two-byte alignment; on most platforms, any object with a non-even
size will fit this criterion.

 template <class T>
 class auto_ptr {
  template <bool can_optimize> class helper;
  helper<sizeof(T) & 1 == 0> my_helper;
 public:
  ...
 };

 // is this dummy definition really needed?
 template <class T, bool can_optimize>
 class auto_ptr<T>::helper<can_optimize> {};

 // portable specialization
 template <class T>
 class auto_ptr<T>::helper<false> {
  T *my_pointer;
  bool mu_owner;
 public:
  helper(T* p, bool o) : my_pointer(p), mu_owner(o) {};
  bool owner() { return o; };
  T* pointer() { return my_pointer; };
  void owner(bool o) { mu_owner = o; };
  void pointer(T* p) { my_pointer = p; };
 };

 // non-portable specialization
 template <class T>
 class auto_ptr<T>::helper<true> {
  typedef unsigned long word;
  word val;
 public:
  helper(T* p, bool o) : val((word) p | o) {}
  bool owner() { return val & 1; }
  T* pointer() { return (T*) (val & ~1); };
  void owner(bool o) { val = ((word) pointer() | o); };
  void pointer(T* p) { val = ((word) p | owner()) };
 }

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]