    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: More cow_ptr&lt;type&gt; Ruminations</title>
        <link>https://members.accu.org/index.php/journals/525</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">Overload Journal #33 - Aug 1999 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c171/">33</a>
                    (8)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c171-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c171+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;More cow_ptr&lt;type&gt; Ruminations</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 August 1999 17:50:54 +01:00 or Thu, 26 August 1999 17:50:54 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id=
"d0e18"></a>Introduction</h2>
</div>
<p>In my previous article I looked at the cow_ptr&lt;&gt;
copy-on-write class. There are still some interesting points
remaining, and a couple of bugs to own up to. Here's what we've
got.</p>
<pre class="programlisting">
template&lt;typename type&gt;
class cow_ptr // moo
{
public: // create/destroy

  explicit cow_ptr(type * p = 0);
  cow_ptr(const cow_ptr &amp; other);
  ~cow_ptr() throw();

public: // assignment

  cow_ptr &amp; operator=(const cow_ptr &amp; rhs);
  void clear(); 
  ... ... ...
private: // plumbing

  cow_ptr(type * ptr, size_t * count);
  void copy();
  ... ... ...
private: // state

  type * ptr;
  size_t * count; 
};

template&lt;typename type&gt;
cow_ptr&lt;type&gt;::cow_ptr(type * p)
{
  auto_ptr&lt;type&gt; safe(p);
  count = new size_t(1);
  ptr = safe.release();
}

template&lt;typename type&gt;
cow_ptr&lt;type&gt;::cow_ptr(const cow_ptr &amp; other)
    : ptr(other.ptr)
    , count(other.count)
{
  ++*count;
}

template&lt;typename type&gt;
cow_ptr&lt;type&gt;::~cow_ptr() throw()
{
  clear();
}

template&lt;typename type&gt;
cow_ptr&lt;type&gt; &amp; cow_ptr&lt;type&gt;::operator=(const cow_ptr &amp; rhs)
{
  cow_ptr old_self(ptr, count);
  ptr = rhs.ptr;
  count = rhs.count;
  ++*count;
  return *this;
}

template&lt;typename type&gt;
void cow_ptr&lt;type&gt;::clear()
{
  if (--*count == 0)
{
  delete count;
  delete ptr;

  count = 0; 
  ptr = 0;
}
}
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e25" id="d0e25"></a>Clearly some
mistake?</h2>
</div>
<p>There's an obvious bug in <tt class="methodname">clear()</tt>.
Both pointers should be reset to null irrespective of the count.
Here's a first attempt at a fix: template&lt;typename type&gt;</p>
<pre class="programlisting">
void cow_ptr&lt;type&gt;::clear()
{
  if (--*count == 0)
  {
    delete count;
    delete ptr;
  }
  count = 0;
  ptr = 0;
}
</pre>
<p>This seems fine. But what if we call <tt class=
"methodname">clear()</tt> twice in succession? That will
dereference a null pointer. Not good. Looking closer, we have two
delete expressions. Can either of them throw an exception? Well,
delete count can't since count is a pointer to a built in type, but
delete ptr can<sup>[<a name="d0e40" href="#ftn.d0e40" id=
"d0e40">1</a>]</sup>. This is a good reason for doing delete ptr
<span class="emphasis"><em>after</em></span> delete count. If
delete ptr does throw an exception what will happen to the cow_ptr
object? Both its pointers will be unchanged, but both will be
invalid. Not good. We want both pointers to be set to null, even if
delete ptr throws an exception:</p>
<pre class="programlisting">
template&lt;typename type&gt;
void cow_ptr&lt;type&gt;::clear()
{
  size_t * old_count = count;
  type * old_ptr = ptr;

  count = 0;
  ptr = 0;

  if (old_count &amp;&amp; --*old_count == 0)
  {
    delete old_count;
    delete old_ptr;
  }
}
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e49" id="d0e49"></a>Bugs</h2>
</div>
<p>Bugs are gregarious creatures. They usually roam about in small
swarms. If you find a bug it's a good bet it will have a few mates
hiding close by...</p>
<pre class="programlisting">
template&lt;typename type&gt;
cow_ptr&lt;type&gt; &amp; cow_ptr&lt;type&gt;::
operator=(const cow_ptr &amp; rhs)
{
  cow_ptr old_self(ptr, count); 
  ptr = rhs.ptr;
  count = rhs.count;
  ++*count;
  return *this;
}
</pre>
<p>The problem is in ++*count; count could be a null pointer. And
of course this problem also crops up in the copy constructor. And
in <tt class="methodname">copy()</tt>...</p>
<pre class="programlisting">
template&lt;typename type&gt;
void cow_ptr&lt;type&gt;::copy()
{
  if (*count &gt; 1)
  {
    cow_ptr unshared(new type(*ptr));
    *this = unshared;
  }
}
</pre>
<p>And in fact it's even worse in <tt class=
"methodname">copy()</tt> because ptr could be null too. If ptr is
null then copy should be a no-op:</p>
<pre class="programlisting">
template&lt;typename type&gt;
void cow_ptr&lt;type&gt;::copy()
{
  if (ptr &amp;&amp; count &amp;&amp; *count &gt; 1)
  {
    cow_ptr unshared(new type(*ptr));
    *this = unshared;
  }
}
</pre>
<p>I told you they were gregarious. Note that you can implement the
copy constructor by calling the assignment operator:</p>
<pre class="programlisting">
template&lt;typename type&gt;
cow_ptr&lt;type&gt;::cow_ptr(const cow_ptr &amp; other)
    : ptr(0)
    , count(0)
{
  *this = other;
}

template&lt;typename type&gt;
cow_ptr&lt;type&gt; &amp; cow_ptr&lt;type&gt;::operator=(const cow_ptr &amp; rhs)
{
  if (ptr != rhs.ptr)
  {
    cow_ptr old_self(ptr, count); 
    ptr = rhs.ptr;
    count = rhs.count;
    if (count) ++*count;
  }
  return *this;
}
</pre>
<p>It's noticeable now that &quot;all roads lead to operator=&quot;. The copy
constructor calls it. And copy() too. It's common to find one
method is the primitive for many others. And you often have a
choice of which one to make the primitive. For example we could
fold the code for <tt class="methodname">clear()</tt> into the
destructor:</p>
<pre class="programlisting">
template&lt;typename type&gt;
cow_ptr&lt;type&gt;::~cow_ptr() throw()
{
  if (count &amp;&amp; --*count == 0)
  {
    delete count;
    delete ptr;
  }
}
</pre>
<p>This would allow <tt class="methodname">clear()</tt> to delegate
to the assignment operator.</p>
<pre class="programlisting">
template&lt;typename type&gt;
void cow_ptr&lt;type&gt;::clear()
{
  static const cow_ptr null(0, 0);
  *this = null;
}
</pre>
<p>It doesn't really matter which way you skin it; the important
thing is to avoid duplication.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e90" id=
"d0e90"></a>Responsibility</h2>
</div>
<p>In one article the regular constructor looked like this:</p>
<pre class="programlisting">
template&lt;typename type&gt;
cow_ptr&lt;type&gt;::cow_ptr(type * p)
    : ptr(p)
    , count(new size_t(1))
{
  // all done
}
</pre>
<p>And then in the following article it looked like this:</p>
<pre class="programlisting">
template&lt;typename type&gt;
cow_ptr&lt;type&gt;::cow_ptr(type * p)
{
  auto_ptr&lt;type&gt; safe(p);
  count = new size_t(1);
  ptr = safe.release();
}
</pre>
<p>Hinges of instability are always worth close scrutiny. The
problem is that <tt class="literal">new size_t(1)</tt> could throw
a <tt class="exceptionname">bad_alloc</tt> exception. If this
happens should the cow_ptr destructor take responsibility for the
pointer parameter or not? In the first version it doesn't, and in
the second version it does. I'm not happy with either version. The
trouble is that the constructor can't know whether it should take
responsibility or not. The client code might require some complex
initialisation. Not good. What to do? Well, why not let the client
decide! One way to do this is with a dummy constructor
parameter<sup>[<a name="d0e109" href="#ftn.d0e109" id=
"d0e109">2</a>]</sup>.</p>
<pre class="programlisting">
struct bound_ptr_t;
extern const bound_ptr_t bound_ptr;

struct loose_ptr_t;
extern const loose_ptr_t loose_ptr;

template&lt;typename type&gt;
class cow_ptr 
{
public:
  cow_ptr(type * p, const bound_ptr_t &amp;);
  cow_ptr(type * p, const loose_ptr_t &amp;);
  ... ... ...
};

template&lt;typename type&gt;
cow_ptr&lt;type&gt;::cow_ptr(type * p, const bound_ptr_t &amp;)
    : ptr(p)
    , count(new size_t(1))
{
  // all done
}

template&lt;typename type&gt;
cow_ptr&lt;type&gt;::cow_ptr(type * p, const loose_ptr_t &amp;)
{
  auto_ptr&lt;type&gt; safe(p);
  count = new size_t(1);
  ptr = safe.release();
}
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e115" id="d0e115"></a>Default
Constructor</h2>
</div>
<p>If you put this extra parameter into the constructor, don't
forget to create a 'genuine' (no default parameters) default
constructor.</p>
<pre class="programlisting">
template&lt;typename type&gt;
cow_ptr&lt;type&gt;::cow_ptr()
    : ptr(0)
    , count(new size_t(1))
{
  // all done
}
</pre>
<p>Notice that the default constructor could throw an exception.
There is an argument that says default constructors for simple
&quot;value&quot; classes should never throw exceptions<sup>[<a name="d0e124"
href="#ftn.d0e124" id="d0e124">3</a>]</sup>. There are a number of
ways you can solve this. Perhaps the most obvious is to not bother
counting the pointer if it's null.</p>
<pre class="programlisting">
template&lt;typename type&gt;
cow_ptr&lt;type&gt;::cow_ptr()
    : ptr(0
    , count(0)
{
  // all done
}
</pre>
<p>This ties in nicely with the fact that count can be null anyway,
thanks to <tt class="methodname">clear()</tt>. However, this is not
the only solution. An alternative is to not throw an exception in
the first place; don't new the <tt class="type">size_t</tt>! The
insight is that we can create a static count of 1. A kind of mini
singleton<sup>[<a name="d0e138" href="#ftn.d0e138" id=
"d0e138">4</a>]</sup>.</p>
<pre class="programlisting">
template&lt;typename type&gt;
class cow_ptr
{
    ... ... ...
private:

  static const size_t one;
  static size_t * const shared_one;

  type * ptr;
  size_t * count;
};

template&lt;typename type&gt;
const size_t cow_ptr&lt;type&gt;::one = 1;

template&lt;typename type&gt;
size_t * const cow_ptr&lt;type&gt;::shared_one = const_cast&lt;size_t*&gt;(&amp;one);

template&lt;typename type&gt;
cow_ptr&lt;type&gt;::cow_ptr()
    : ptr(p)
    , count(shared_one)
{
  // all done
}
</pre>
<p>This may seem a tad strange, but it has some unexpected
benefits. The responsibility problem in the pointer parameter
constructor vanishes, allowing:</p>
<pre class="programlisting">
template&lt;typename type&gt;
cow_ptr&lt;type&gt;::cow_ptr(type * p)
    : ptr(p)
    , count(shared_one)
{
    // all done
}
</pre>
<p>Clearly this will require some careful coding elsewhere, but it
can be made to work. I'll look at this more fully next time.</p>
<p>Thanks to Kevlin for his comments and advice.</p>
<p>That's all for now. Cheers</p>
</div>
<div class="footnotes"><br>
<hr class="c2" width="100">
<div class="footnote">
<p><sup>[<a name="ftn.d0e40" href="#d0e40" id=
"ftn.d0e40">1</a>]</sup> I know it shouldn't, but most programmers
are only human, and sooner or later an exception will leak out a
destructor. Probably sooner.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e109" href="#d0e109" id=
"ftn.d0e109">2</a>]</sup> Similar to placement new.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e124" href="#d0e124" id=
"ftn.d0e124">3</a>]</sup> Consider loading objects from persistent
storage for example.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e138" href="#d0e138" id=
"ftn.d0e138">4</a>]</sup> I first saw this idea suggested by
Kevlin.</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
