    <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  :: From Mechanism to Method</title>
        <link>https://members.accu.org/index.php/articles/352</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>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #55 - Jun 2003</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/articles/">All</a>

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

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

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

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

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

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c192/">55</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-192/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+192/">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;From Mechanism to Method</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 02 June 2003 22:57:04 +01:00 or Mon, 02 June 2003 22:57:04 +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>
<div>
<h3>Distinctly Qualified</h3>
</div>
<p>The standard library string type is a product of elegance and
sufficiency.</p>
<p>OK, OK, just kidding. If it looks like the product of design by
committee it's because it was. If you appreciate minimalist design
its baroqueness is certain to disappoint.</p>
<p>The road to Hell is paved with good intentions, and the standard
library string is full of good intentions. The standard <tt class=
"literal">basic_string</tt> class template started life as a simple
class and reached its middle age as an over-parameterized class
template with a bad name and a bloated interface. The process of
standardization added somewhat more than two cents worth: What
about generalization for internationalization? What about copy
optimization through reference counting? What about customizing its
memory allocation? What about safe indexing? What about reverse
search operations that mirror each forward search operation? What
about support for STL? And support for similar index-based
operations? You see, good intentions every one of them. But too
much compromise in design leads to a compromised design.</p>
<p>In spite of this criticism, I use the standard string type. For
one thing, it's standard, and for another it satisfies more of my
string needs than a vanilla <tt class="literal">char *</tt>. More
positively, inside this behemoth is a small class (or two)
struggling to get out. There is a sense of obligation to try to
release and realize it. In this article I don't want to address
each and every last detail of such a redesign, but I would like to
outline an approach. In particular, I want to declutter the
interface a little to clear the path to a better understanding of
something that has haunted string classes for the last decade or
so: the specter of copy optimization through reference counting and
copy-on-write.</p>
<p>The issues thrown up by reference counting can be tackled head
on, with limited success, or tackled laterally. The resolution lies
in a combination of restraint and substitutability principles
[<a href="#Henney2000">Henney2000</a>], and in particular treating
const qualification as a form of type separation [<a href=
"#Henney2001a">Henney2001a</a>, <a href=
"#Henney2001b">Henney2001b</a>].</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e46" id="d0e46"></a>Minimalism</h2>
</div>
<p>The open secrets of good design practice include the importance
of knowing what to keep whole, what to combine, what to separate,
and what to throw away.</p>
<p>We can start with the name. Names are important. Hiding the
templatedness of strings does not actually help the reader in any
way, except perhaps to discourage them to think of or use strings
as templated abstractions. The reason we are left with the common
<tt class="literal">typedef</tt>ed names of <tt class=
"literal">string</tt> and <tt class="literal">wstring</tt>, and the
cumbersome underlying names of <tt class=
"literal">basic_string&lt;char&gt;</tt> and <tt class=
"literal">basic_string&lt;wchar_t&gt;</tt>, is historical.
Originally, in the pre-STL era, the proposed standard library was
light on templates - in fact it was quite light, period - and
<tt class="literal">string</tt> and <tt class=
"literal">wstring</tt> were classes. In modern C++ programming we
are more familiar with template usage, and would not be quite so
reticent about the names or accepting of the supposed benefit of
hiding templated usage. If we consider strings to be templated with
respect to their character type, then so be it: <tt class=
"literal">string&lt;char&gt;</tt> and <tt class=
"literal">string&lt;wchar_t&gt;</tt> are clearer, more direct, and
proud to be templated.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e80" id=
"d0e80"></a>Orthogonality</h2>
</div>
<p>Designing a string class is more of a challenge than many people
appreciate. If you have not already done so (several times) it's
worth a try: It's a good C++ work out - memory management, operator
overloading, optimization, etc. The problem is not so much in
language features or implementation, but in interface. What problem
is a string designed to solve? Without a clear focus you discover
that everyone has a slightly different view of what a string should
be: a self-managed array of characters; a wrapper for <tt class=
"literal">char *</tt> and <tt class="literal">&lt;cstring&gt;</tt>;
a small piece of text that requires simple access and
concatenation; a potentially large stretch of text that requires
efficient slicing and rearrangement operations; regular-expression
searchable text; and so on. The problem is one of choice: All of
these suggestions are reasonable, but satisfying them all
simultaneously is not. Any attempt to create a single string class
that does so cannot succeed. We have enough existence proofs to
back this up.</p>
<p>There is already an excellent example of how to solve this
design problem in the standard library: the STL. The STL stands
head and shoulders above other container libraries because it is
not a container library: It is a specification that defines
independent, open-ended families of algorithms, function objects,
iterators, and containers along with the requirements that allow
them to be combined. Independent ideas are expressed independently,
with algorithms separated from underlying container representation
through iterators and from functional specifics through function
objects. This orthogonal design separates concerns quite clearly.
The added bonus is that you get some predefined algorithms,
function objects, iterators, and containers thrown into the
deal.</p>
<p>There is no single container class that satisfies all of our
needs, so we have requirements and exemplars in the library. Given
that we now know that asking how to write a single string class is
the wrong design question, we can see how the cleaner STL-style
solution can be applied to strings. In the first instance, we can
consider strings to be sequences. Their bit-copyable elements,
common use of null termination, conversions, concatenation, and I/O
further characterize them. If we start with this, we end up with a
minimal interface that can be satisfied by lightweight char *
wrappers and scalable string implementations - such as SGI's rope
template [<a href="#SGI">SGI</a>] - and even <tt class=
"literal">std::basic_string</tt>. The more complex functionality
associated with different string types is then expressed
orthogonally through algorithms, so that new algorithms can act on
all strings and new strings can take advantage of old algorithms.
Now, should we want an all-singing, all-dancing, killerapp,
last-one-you'll-ever-need string, we can write our own - so long as
it satisfies the base requirements of what is means to be a
string.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e101" id="d0e101"></a>Choice</h2>
</div>
<p>An interface should represent reasonable goals and present its
user with reasonable choices - overachieving interfaces are weaker
and more complex, not stronger and simpler.</p>
<p>Consider, for instance, the issue of subscripting. <tt class=
"literal">operator[]</tt> is not required to perform bounds
checking whereas <tt class="literal">at</tt> is. Indexing out of
bounds causes undefined behavior for <tt class=
"literal">operator[]</tt> and an <tt class=
"literal">out_of_range</tt> exception for <tt class=
"literal">at</tt>. On the surface, this looks like a reasonable
choice: You get to choose the quality of failure for yourself. The
problem is that such an option is utterly useless and cannot be
reasonably exercised. When would you consciously choose to write
code that needed <tt class="literal">at</tt> rather than <tt class=
"literal">operator[]</tt>? If you make the choice, you have already
anticipated the bug, and can therefore prevent it.</p>
<p>If you have a choice, it should be reasonable to exercise it. It
should also be possible to exercise it. Take allocators. Please.
The world of containers would be far simpler without them and very,
very few people would miss them. People that actually need to
customize their memory allocation - for shared memory, for
persistence, for the sake of it - find themselves working against
rather than with the allocator model. Trying effective memory
management of a container whose representation and management is
not fully open to you is like eating with a knife and fork... held
with chopsticks... through mittens. If you are serious about
managing the allocation of a container, then get serious and manage
it: Write your own container type. It is simpler, more likely to
work, and is very much in the extensible spirit of the STL - more
so than limiting yourself to the handful of default container
implementations in <tt class="literal">std</tt>.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e134" id=
"d0e134"></a>Consistency</h2>
</div>
<p>Another property of a well-designed interface is consistency.
Some functions in <tt class="literal">basic_string</tt> throw
exceptions on failure, whereas others do not. This is already
inconsistent, but is made more so by the presence of both
<tt class="literal">operator[]</tt> and <tt class=
"literal">at</tt>. If <tt class="literal">operator[]</tt> is
shadowed by the exception-throwing at, then where are the
exception-throwing doubles for iteration? If an exception-throwing
access operator is considered reasonable, you should expect -
indeed, demand - safe and unsafe variants for other forms of
access. After all, what is good for the goose is good for the
gander. However, we have established that at is not reasonable, so
there is no need to clutter up the string interface any
further.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e151" id="d0e151"></a>Mad COW
Disease</h2>
</div>
<p>Strings get copied. Fact of life. Copy assignment and
construction afford strings their value-based behavior. But strings
are not lightweight classes. They encapsulate a heap allocated
representation, and copying could be expensive, especially if the
copied string is never modified:</p>
<pre class="programlisting">
template&lt;typename char_type&gt;
class string 
{
  ...
private:
  ...

  size_t used, reserved; // current
                         // length and allocated space
  char_type *text; // allocated and
                   // deallocated representation
};
</pre>
<p>The compiler is entitled to a number of optimizations. For
instance, the following:</p>
<pre class="programlisting">
std::string cow = &quot;Woof!&quot;;
</pre>
<p>Is equivalent to:</p>
<pre class="programlisting">
std::string cow = std::string(&quot;Woof!&quot;);
</pre>
<p>But can be - and normally is - optimized to:</p>
<pre class="programlisting">
std::string cow(&quot;Woof!&quot;);
</pre>
<p>For assignment, overloading <tt class="literal">operator=</tt>
to take a <tt class="literal">const char *</tt> prevents a
conversion to a temporary that is then used with the ordinary copy
assignment operator.</p>
<p>The result of string concatenation is a temporary string
object:</p>
<pre class="programlisting">
std::string loud_cow = cow + &quot;!!&quot;;
</pre>
<p>Here <tt class="literal">operator+</tt> returns a temporary
<tt class="literal">std::string</tt> object that is used to
initialize <tt class="literal">loud_cow</tt>. Depending on how the
called function is written, the named return value optimization
(NRV) allows a compiler to construct directly into <tt class=
"literal">loud_cow</tt> [<a href="#Ellis-1990">Ellis-1990</a>,
<a href="#Lippman1996">Lippman1996</a>] rather than create an
additional temporary object. This optimization applies only to copy
construction, not copy assignment: If <tt class=
"literal">loud_cow</tt> is assigned the result of the
concatenation, a temporary is created and then discarded.
Similarly, in the following initialization two temporaries are
created, only one of which can be optimized away by the NRV:</p>
<pre class="programlisting">
std::string loud_cow = cow + &quot; &quot; + cow;
</pre>
<p>Because value objects of class type are commonly passed around
by <tt class="literal">const</tt> reference, copying typically
happens through assignment, data member initialization, and return
values. We can see that the compiler already has considerable
license to optimize, and that techniques such as overloading to
prevent conversions and preferring initialization to construction
help reduce the temporary burden, so to speak. But in complex
expressions and initialization of data members we can also see that
there may still be the need to amortize the cost of copying.</p>
<p>What is required of an optimization? Transparency - so it is
substitutable for the unoptimized version - and optimization - many
optimizations aren't. In particular, the requirement of
transparency means that users should not be entertained by new and
interesting bugs.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e214" id="d0e214"></a>Counting the
Bodies</h2>
</div>
<p>The most common copy optimization is to share the representation
of a string when a copy is made rather than make a deep copy that
results in heap allocation. This means that copying is simple and
cheap. Only when the string is going to be modified does the 'real'
copy occur to avoid aliasing surprises. This lazy, just-in-time
model - commonly referred to as <span class="emphasis"><em>copy on
write</em></span> - defers the cost of allocation until the point
it is absolutely needed. If it is never needed, the cost is not
paid. However, few things in life are for free: The sharing is not
without overhead. For a start, it must be managed, which increases
the complexity of the code. The referencing must also be tracked so
that when - as a result of assignment or destruction - a string's
text body is no longer referenced it is properly deallocated, and
when only a single string handle refers to a text body, redundant
deep copies are not made.</p>
<p>There are five ways in which references held by string handles
to text bodies can be sensibly tracked, each with its own
particular tradeoffs:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p><span class="emphasis"><em>Hold separate pointers to the
reference count and the actual text.</em></span> This means that
the footprint of the string object is a little larger and that we
are paying for the allocation of two heap objects. The allocation
means that it is unlikely that we recoup our investment unless a
text body is shared by more than two string handles. For a single
reference, this is a not an optimization. Holding a <tt class=
"literal">static</tt> reference count of <tt class=
"literal">1</tt>, and only allocating a dynamic count when the
figure rises above that can reduce the overhead in this case. This
will complicate the implementation, but if the majority of strings
are never copied this will be a saving. If, on the other hand, the
string handle's footprint is a concern, the information duplicated
between sharing handles can also be associated with the count,
reducing the footprint to two pointers:</p>
<pre class="programlisting">
template&lt;typename char_type&gt;
class string 
{
  ...
private:
  ...
  struct shared 
  {
    size_t used, reserved, count;
  };
  shared *info;
  char_type *text;
};
</pre></li>
<li>
<p><span class="emphasis"><em>Hold a single pointer to an object
that contains the reference count, the pointer to the shared text,
and the text size information.</em></span> This always results in
the allocation of two objects on the heap, and there is an extra
level of indirection to reach the actual text. For some designs
this could provide an additional benefit of allowing the actual
text to be reallocated or virtualized in some way, e.g. to disk,
without affecting the handle objects. In the common case, the main
benefits of this approach are a little more restricted. The string
handle's footprint has now been reduced to a single pointer and, if
you want to add a constructor and destructor to the shared body,
the management of the text memory can be hidden from the string
handle. In its simplest form we can see the basic rearrangement is
a proper handle-body configuration [<a href=
"#Coplien1992">Coplien1992</a>, <a href=
"#Gamma-1995">Gamma-1995</a>]:</p>
<pre class="programlisting">
template&lt;typename char_type&gt;
class string 
{
  ...
private:
  ...
  struct shared 
  {
    size_t used, reserved, count;
    char_type *text;
  };
  shared *body;
};
</pre></li>
<li>
<p><span class="emphasis"><em>Hold a single pointer to memory that
contains both the information about the string text - including the
reference count - and the string text itself.</em></span> The
information is held as a prefix to the <tt class=
"literal">char_type</tt> array. Only a single pointer is held in
the handle, only a single allocation is performed, and treating the
space before the text as a different type allows access to the
string information. Although this solution is at a slightly lower
level, it can be very effective [<a href=
"#Henney1998">Henney1998</a>], especially when encapsulated within
the string handle. The drawbacks to this approach are that any
resize must also involve reallocating and copying the information
prefix, and also the intent of the code and connections between the
data structures is less obvious:</p>
<pre class="programlisting">
template&lt;typename char_type&gt;
class string 
{
  ...
private:
  ...
  struct shared 
  {
    size_t used, reserved, count;
  };
  char_type *text; // reinterpret_cast
                   // &lt;shared *&gt;(text) - 1
};
</pre></li>
<li>
<p><span class="emphasis"><em>Link copied objects together in a
doubly-linked list and hold a pointer to the string
text.</em></span> The information about the string text can be held
duplicated in each string handle or as a prefix of the text body's
memory. When the links going to the previous and next string handle
are both null (or, in a circular configuration, pointing to
<tt class="literal">this</tt>) the text body is uniquely owned.
This style of reference accounting (it is not really reference
counting because there is no explicit count) is perhaps least
appropriate for strings because there are no operations that
require traversal of all handles. Each string handle will have a
larger footprint than the other solutions considered so far,
although only a single allocation is required per text body:</p>
<pre class="programlisting">
template&lt;typename char_type&gt;
class string 
{
  ...
private:
  ...
  size_t used, reserved;
  char_type *text;
  string *previous, *next;
};
</pre></li>
<li>
<p><span class="emphasis"><em>Hold the string text in a managed
lookup table and retain some kind of reference into the
table.</em></span> The information about the string can be held
alongside the actual text in the table. This approach is suitable
when the aim is not simply to reduce copy cost, but also to
eliminate any duplicate strings. It is effectively a symbol table.
The cost of initialization from a raw string is increased because
of an initial search and a possible initial insertion, and there is
increased space overhead per text body that exists. Strings can be
held uniquely so that some string features, such as reserved
capacity, are no longer appropriate. For strings, the typical
implementation is to hold a <tt class="literal">static</tt>
repository, which introduces its own issues as far as
initialization and finalization ordering. This is typically not a
suitable design for general purpose strings:</p>
<pre class="programlisting">
template&lt;typename char_type&gt;
class string 
{
  ...
private:
  ...
  struct less {...}; // function object
                     // type for comparison
  struct info 
  {
    size_t used, count;
  };

  typedef map&lt;const char_type *, info, less&gt; string_map;
  static string_map strings;
  string_map::iterator entry;
};
</pre></li>
</ol>
</div>
<p>Clearly, there are many ways to skin a cow. For general-purpose,
copy-on-write strings, the first three techniques are the most
appropriate and most common.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e286" id="d0e286"></a>Trying to be
Smart</h2>
</div>
<p>It seems clear that non-<tt class="literal">const</tt>
operations such as <tt class="literal">operator+=</tt> and
<tt class="literal">resize</tt> require a string handle to operate
on its own copy of the text body. It also seems clear that
<tt class="literal">const</tt> operations, such as <tt class=
"literal">size</tt> and <tt class="literal">compare</tt>, can
operate without ill effect on a shared representation. This seems
to divide operations in the string world neatly into two type
types. However, there is a grey territory in between. What about
non-<tt class="literal">const</tt> <tt class=
"literal">operator[]</tt>? This operator may be used for both
reading from and writing to a string:</p>
<pre class="programlisting">
string&lt;char&gt; cow = &quot;Woof!&quot;, ghost = cow;
ghost[3] = cow[1];
</pre>
<p>Both of these calls result in a call to the non-<tt class=
"literal">const</tt> <tt class="literal">operator[]</tt>, but for
assignment we want to assure that a deep copy happens, but for
reading a deep copy would be wasteful. There is no way to
distinguish between these uses within <tt class=
"literal">operator[]</tt>. What we need is a smarter reference to
do the work for us:</p>
<pre class="programlisting">
template&lt;typename char_type&gt;
class string 
{
public:
  class reference 
  {
  public:
    ...
    char &amp;operator=(char); // perform
                           // deep copy before write
    operator char() const; // use shared
                           // representation
  private:
    string *target;
    size_t index;
  };
  reference operator[](size_t);
  ...
};
</pre>
<p>This smart reference approach works in most cases. However, a
smart reference is not totally substitutable for a real reference.
The following fails to compile because <tt class=
"literal">std::swap</tt> expects real references:</p>
<pre class="programlisting">
swap(cow[3], ghost[1]);
</pre>
<p>There are other problems with the smart reference approach for
strings [<a href="#Meyers1996">Meyers1996</a>, <a href=
"#Sutter1998a">Sutter1998a</a>], some of which are related to
dubious practice - holding the address of a returned reference -
and others to do with constraints in the standard - the <tt class=
"literal">reference</tt> type is required to be a real reference,
no smart references allowed.</p>
<p>And don't think that the problem is just confined to <tt class=
"literal">operator[]</tt>: It also applies to the <tt class=
"literal">iterator</tt> type, which may be used for both reading
and writing. Therefore, for reference-counted strings, <tt class=
"literal">iterator</tt> must be a smart pointer rather than raw
pointer type for the reference-counting optimization to be fully
effective.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e359" id=
"d0e359"></a>Pessimism</h2>
</div>
<p>The outlook is pessimistic. As a copy optimization the
effectiveness of copy-on-write reference counting has been reduced
to a few cases. In other cases it may be quite the opposite of an
optimization, regardless of the investment and increase in code
complexity.</p>
<p>The only workable evaluation model for these problem functions
is a pessimistic one: You don't know whether the user is going to
read or write through the returned reference, and you have to just
accept that and assume the worst. You may also consider catching
some of the corner cases for undefined behavior, such as holding
onto the address of a returned reference. In these cases you have
to prevent any future sharing, so that if the current string is
used as the source for a copy it causes a deep copy rather than
sharing:</p>
<pre class="programlisting">
template&lt;typename char_type&gt;
class string 
{
public:
  typedef char_type *iterator;
  iterator begin() 
  {
    reserve();
    return text;
  }
  void reserve(); // reserve
                  // representation exclusively
  ...
private:
  ...
  char_type *text;
};
</pre>
<p>All in all, this further reduces the effectiveness of copy
optimization to a few corner cases. For non-<tt class=
"literal">const</tt> cases there appears little to be gained from
considering this a general-purpose optimization.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e373" id=
"d0e373"></a>Threadbare</h2>
</div>
<p>The final body blow comes with the introduction of
multithreading. Sharing a reference-counted text body becomes
unnecessarily interesting when the sharing is between threads. The
gut instinct of programmers new to threaded programming is that a
mutex or equivalent synchronization primitive will solve the
problem. For instance:</p>
<pre class="programlisting">
template&lt;typename char_type&gt;
class string 
{
  ...
private:
  ...
  struct shared 
  {
    size_t used, reserved, count;
    mutex guard;
    char_type *text;
  };
  shared *body;
};
</pre>
<p>Synchronization primitives are operating system resources, and
as such may be potentially scarce and costly to obtain. The
temptation is then to share a common mutex for all string
objects:</p>
<pre class="programlisting">
template&lt;typename char_type&gt;
class string 
{
  ...
private:
  ...
  struct shared 
  {
    size_t used, reserved, count;
    char_type *text;
  };
  static mutex guard;
  shared *body;
};
</pre>
<p>In addition to the initialization and finalization issues, you
now have another problem: performance. First of all, locking and
unlocking mutexes for all data accesses comes with a measurable
overhead. And second, all string objects are now serialized through
the same mutex, creating a potential bottleneck. Given that the aim
of copy-on-write reference counting is to optimize - and taken with
all the other issues raised previously - a mutex-based approach is
not even on the radar.</p>
<p>If you look carefully at what you need to lock, you will see
that the locking revolves around the reference count. Many
operating systems provide you with lock-free synchronization
primitives for incrementing and decrementing integers, e.g.
<tt class="literal">InterlockedIncrement</tt> and <tt class=
"literal">InterlockedDecrement</tt> on Win32. With careful coding
it is now possible to ensure that no shared text body is ever
compromised by race conditions. But note that these primitives
still incur a performance penalty - few things in life are
free.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e394" id="d0e394"></a>Separation of
Concerns</h2>
</div>
<p>There is a question we have to ask ourselves: Is it all worth
it? The assumption has always been there that this is a good
general-purpose optimization, from the early days of
standardization [<a href="#Teale1991">Teale1991</a>] to the current
standard [<a href="#ISO1998">ISO1998</a>]. At every stage,
accommodating this style of implementation has caused headaches,
even without the threading issues. The concern is not a recent one
[<a href="#Murray1993">Murray1993</a>]: &quot;<span class="quote">A
use-counted class is more complicated than a non-usecounted
equivalent, and all of this horsing around with use counts takes a
significant amount of processing time. If the time spent copying
values is small enough (either because the values are small and
cheap to copy or they are not copied very often), changing the
class to do use counting may make programs slower. Always do some
performance measurements when making this kind of change to
convince yourself that this optimization is not really a
pessimization!</span>&quot;</p>
<p>With multithreading the issues become even more involved
[<a href="#Sutter1998b">Sutter1998b</a>] and the horsing around
becomes a full-blown stampede (but hopefully not a race
condition&hellip;). This simply reinforces an earlier conclusion:
It is not possible to design a single string implementation that
satisfies all uses. Thus the default implementation that causes the
fewest surprises (bugs) - either in use or in implementation - is
to avoid copy-on-write reference counting. Avoiding it, or
providing explicit information on how to disable it, is the
approach now adopted by many libraries [<a href=
"#Dinkum">Dinkum</a>, <a href="#SGI">SGI</a>].</p>
<p>So deeply rooted is the idea that copy-on-write reference
counting is mandatory for strings that many developers are shocked
- and sometimes go into denial - when they discover that the return
on investment in this technique is often negligible and sometimes
negative. Also have a look at <a href="http://laguiolesteakknivesreview.com/">Laguiole steak knives</a>. The long-standing belief in this old practice is,
however, younger than faith in another more fundamental software
engineering principle: separation of concerns. And hey, do we have
concerns.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e423" id="d0e423"></a>A Qualified
Difference</h2>
</div>
<p>Listen to the code, it is trying to tell you something: Mixing
reference counting with mutability causes problems. Period.
However, if you listen closely, you can hear a leading question,
the whisper of a solution: What if you don't mix reference counting
with mutability? What if we are dealing with two related but
distinct types?</p>
<p>From an interface perspective, we can see that we can use a
string either as something that is read-mostly information or as a
read-and-write space. From an implementation perspective, problems
with reference counting arise only with mutability. Previously we
explored the idea of <tt class="literal">const</tt> qualification
being a form of subtype relationship [<a href=
"#Henney2001a">Henney2001a</a>] and one that can be reflected in
inheritance [<a href="#Henney2001b">Henney2001b</a>]. For value
types we can define separate classes, not related through
inheritance, and provide substitutability through conversions
[<a href="#Henney2000">Henney2000</a>].</p>
<p>Consider a design where string covers the general case and
something like <tt class="literal">const_string</tt> covers the
immutable case. <tt class="literal">const_string</tt> has a subset
of the operations of string: the <tt class="literal">const</tt>
ones plus some that effect a rebinding of handle to text body, such
as <tt class="literal">operator=</tt>. <tt class=
"literal">const_string</tt> is different to <tt class=
"literal">const string</tt>, which prevents all modification but
still comes with any baggage not relevant to <tt class=
"literal">const</tt>, e.g. reserved capacity. It is more like the
relationship between <tt class="literal">iterator</tt> and
<tt class="literal">const_iterator</tt>.</p>
<p>Not only do <tt class="literal">string</tt> and <tt class=
"literal">const_string</tt> differ in interface, but they can also
differ in implementation: string should not be reference counted
but <tt class="literal">const_string</tt> may be. <tt class=
"literal">const_string</tt> has none of the concerns that plagued
copyon-write for a mutable string, and thread safety can be catered
for by atomic increment and decrement operations.</p>
<p>Before you get too attached to the names <tt class=
"literal">string</tt> and <tt class="literal">const_string</tt> -
and assuming that your compiler fully supports partial template
specialization - consider one last refinement that uses template
specialization and lets us keep a single name:</p>
<pre class="programlisting">
template&lt;typename char_type&gt;
class string 
{
  ...
private:
  ...
  size_t used, reserved;
  char_type *text; // unshared
};

template&lt;typename char_type&gt;
class string&lt;const char_type&gt; 
{
  ...
private:
  ...
  struct shared 
  {
    const size_t used;
    size_t count;
  };
  char_type *text; // reinterpret_cast
                   // &lt;shared *&gt;(text) - 1
};
</pre>
<p>With this approach <tt class="literal">string&lt;char&gt;</tt>
is a common, writeable string and <tt class=
"literal">string&lt;const char&gt;</tt> is the idiom used to work
with the read-only variant.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e503" id=
"d0e503"></a>Conclusion</h2>
</div>
<p>What do you get when cross a string class with copy-on-write
reference counting? A problem. What do you get when you cross that
with separation according to qualification? A solution.</p>
<p>The road to optimization is full of potholes. Trying to shoe
horn many interface and implementation possibilities into a single
type leads to twisted back roads. Separating core representation
from algorithmic abstraction can clarify and clean up a string
interface. Separation according to qualification is also a
simplifying decision, both for interface and implementation. A cure
- in strings at least - for Mad COW Disease<sup>[<a name="d0e510"
href="#ftn.d0e510" id="d0e510">1</a>]</sup>.</p>
<div class="sidebar">
<p>This article was originally published on the <i class=
"citetitle">C/C++ Users Journal C++ Experts Forum</i> in May 2001
at <a href="http://www.cuj.com/documents/s=7995/cujcexp1905henney/"
target=
"_top">http://www.cuj.com/documents/s=7995/cujcexp1905henney/</a>.
Thanks to Kevlin for allowing us to reprint it.</p>
</div>
</div>
<div class="bibliography">
<div class="titlepage">
<h2><a name="d0e523" id="d0e523"></a>References</h2>
</div>
<div class="bibliomixed"><a name="Coplien1992" id=
"Coplien1992"></a>
<p class="bibliomixed">[Coplien1992] James Coplien, <span class=
"citetitle"><i class="citetitle">Advanced C++: Programming Styles
and Idioms</i></span>, Addison-Wesley, 1992.</p>
</div>
<div class="bibliomixed"><a name="Dinkum" id="Dinkum"></a>
<p class="bibliomixed">[Dinkum] The Dinkum C++ Library, Dinkumware
Ltd, <span class="bibliomisc"><a href="http://www.dinkumware.com/"
target="_top">http://www.dinkumware.com/</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Ellis-1990" id="Ellis-1990"></a>
<p class="bibliomixed">[Ellis-1990] Margaret Ellis and Bjarne
Stroustrup, <span class="citetitle"><i class="citetitle">The
Annotated C++ Reference Manual</i></span>, Addison-Wesley,
1990.</p>
</div>
<div class="bibliomixed"><a name="Gamma-1995" id="Gamma-1995"></a>
<p class="bibliomixed">[Gamma-1995] Erich Gamma, Richard Helm,
Ralph Johnson, and John Vlissides, <span class=
"citetitle"><i class="citetitle">Design Patterns: Elements of
Reusable Object-Oriented Software</i></span>, Addison-Wesley,
1995.</p>
</div>
<div class="bibliomixed"><a name="Henney1998" id="Henney1998"></a>
<p class="bibliomixed">[Henney1998] Kevlin Henney, &quot;Counted Body
Techniques&quot;, Overload 25, April 1998, also available from
<span class="bibliomisc"><a href="http://www.curbralan.com" target=
"_top">http://www.curbralan.com</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Henney2000" id="Henney2000"></a>
<p class="bibliomixed">[Henney2000] Kevlin Henney, &quot;From Mechanism
to Method: Substitutability&quot;, C++ Report 12(5), May 2000, also
available from <span class="bibliomisc"><a href=
"http://www.curbralan.com" target=
"_top">http://www.curbralan.com</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Henney2001a" id=
"Henney2001a"></a>
<p class="bibliomixed">[Henney2001a] Kevlin Henney, &quot;From Mechanism
to Method: Good Qualifications&quot;, <span class="citetitle"><i class=
"citetitle">C/C++ Users Journal C++ Experts Forum</i></span>,
January 2001, <span class="bibliomisc"><a href=
"http://www.cuj.com/experts/1901/henney.html" target=
"_top">http://www.cuj.com/experts/1901/henney.html</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Henney2001b" id=
"Henney2001b"></a>
<p class="bibliomixed">[Henney2001b] Kevlin Henney, &quot;From Mechanism
to Method: Total Ellipse&quot;, <span class="citetitle"><i class=
"citetitle">C/C++ Users Journal C++ Experts Forum</i></span>, March
2001, <span class="bibliomisc"><a href=
"http://www.cuj.com/experts/1903/henney.html" target=
"_top">http://www.cuj.com/experts/1903/henney.html</a></span>.</p>
</div>
<div class="bibliomixed"><a name="ISO1998" id="ISO1998"></a>
<p class="bibliomixed">[ISO1998] <span class="citetitle"><i class=
"citetitle">International Standard: Programming Language -
C++</i></span>, ISO/IEC 14882:1998(E), 1998.</p>
</div>
<div class="bibliomixed"><a name="Lippman1996" id=
"Lippman1996"></a>
<p class="bibliomixed">[Lippman1996] Stanley Lippman, <span class=
"citetitle"><i class="citetitle">Inside the C++ Object
Model</i></span>, Addison-Wesley, 1996.</p>
</div>
<div class="bibliomixed"><a name="Meyers1996" id="Meyers1996"></a>
<p class="bibliomixed">[Meyers1996] Scott Meyers, <span class=
"citetitle"><i class="citetitle">More Effective C++: 35 New Ways to
Improve Your Programs and Designs</i></span>, Addison-Wesley,
1996.</p>
</div>
<div class="bibliomixed"><a name="Murray1993" id="Murray1993"></a>
<p class="bibliomixed">[Murray1993] Robert Murray, <span class=
"citetitle"><i class="citetitle">C++ Strategies and
Tactics</i></span>, Addison-Wesley, 1993.</p>
</div>
<div class="bibliomixed"><a name="SGI" id="SGI"></a>
<p class="bibliomixed">[SGI] SGI Standard Template Library
Programmer's Guide, <span class="bibliomisc"><a href=
"http://www.sgi.com/tech/stl/" target=
"_top">http://www.sgi.com/tech/stl/</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Sutter1998a" id=
"Sutter1998a"></a>
<p class="bibliomixed">[Sutter1998a] Herb Sutter, &quot;GotW #44:
Reference Counting - Part II&quot;, September 1998, <span class=
"bibliomisc"><a href="http://www.gotw.ca/gotw/044.htm" target=
"_top">http://www.gotw.ca/gotw/044.htm</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Sutter1998b" id=
"Sutter1998b"></a>
<p class="bibliomixed">[Sutter1998b] Herb Sutter, &quot;GotW #45:
Reference Counting - Part III&quot;, October 1998, <span class=
"bibliomisc"><a href="http://www.gotw.ca/gotw/045.htm" target=
"_top">http://www.gotw.ca/gotw/045.htm</a></span>.</p>
</div>
<div class="bibliomixed"><a name="Teale1991" id="Teale1991"></a>
<p class="bibliomixed">[Teale1991] Steve Teale, &quot;Proposing a C++
String Class Standard&quot;, <span class="citetitle"><i class=
"citetitle">Dr. Dobb's Journal</i></span>, October 1991.</p>
</div>
</div>
<div class="footnotes"><br>
<hr class="c3" width="100">
<div class="footnote">
<p><sup>[<a name="ftn.d0e510" href="#d0e510" id=
"ftn.d0e510">1</a>]</sup> Thanks to Andrei Alexandrescu's original
use of the Mad COW term on comp.std.c++</p>
</div>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
