    <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  :: C++ Standards - The &quot;swap&quot; Problem</title>
        <link>https://members.accu.org/index.php/journals/466</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 #41 - Feb 2001 + Design of applications and programs</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/c163/">41</a>
                    (7)
<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/c67/">Design</a>
                    (236)
<br />

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

                    -                        <a href="https://members.accu.org/index.php/journals/c163+67/">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;C++ Standards - The &quot;swap&quot; Problem</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 February 2001 16:46:05 +00:00 or Mon, 26 February 2001 16:46:05 +00: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></h2>
</div>
<p>The C++ Language Standard was approved in 1998 and is likely to
remain unchanged for some years. So why does the standards
committee still meet? Well, the obvious reason is that in any work
of this size there are both bugs and features that do not work
properly. While those on the committee did their best to desk check
it was published before any compiler or library implementation was
completely in step with it (Indeed, at the time of writing there is
still no conforming implementation publicly available - although I
expect this to change soon.)</p>
<p>This article explores one such problem - a feature that does not
quite work in an acceptable manner. It has cropped up in a number
of forms, and in a number of places - I know of discussions on
accu-general, comp.lang.c++.moderated and boost.org. My name got
associated with it because I submitted a defect report on the
subject, the function &quot;swap&quot; became associated with it because it
provides an easy to understand example.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e24" id="d0e24"></a>A motivating
example</h2>
</div>
<p>Consider a user-defined class:</p>
<pre class="programlisting">
class client {
public:
  . . . 
  void swap(client&amp; that);
private:
  typedef std::vector&lt;int&gt; lookup_table;
  std::string name;
  lookup_table xref;
  int id;
};
</pre>
<p>and a possible implementation of <tt class=
"methodname">client::swap()</tt>...</p>
<pre class="programlisting">
void client::swap(client&amp; that) {
using std::swap;
swap(name, that.name);
swap(xref, that.xref);
swap(id, that.id);
}
</pre>
<p>This is clear, exception safe (if you want to be technical it
meets the &quot;no-throw guarantee&quot;), and efficient. It would be
difficult to justify to most developers that it is poor style and
fragile. However, as we shall see, that is indeed the consequence
of the standard.</p>
<p>Suppose during the course of maintenance a developer decided to
change the above <tt class="literal">typedef</tt> to...</p>
<pre class="programlisting">
typedef arg::vector&lt;int&gt; lookup_table;
</pre>
<p>For the sake of argument suppose the author of <tt class=
"classname">arg::vector</tt> intends it to be a &quot;drop in&quot;
replacement for <tt class="classname">std::vector</tt>. In practice
the change compiles and the functionality is unchanged.</p>
<p>A large part of the C++ standard library is made up of a
supposedly extensible range of containers and algorithms (this part
of the library is often known by its earlier name of STL). The
whole philosophy behind the STL is that new containers and
algorithms can be introduced and work seamlessly.</p>
<p>Consequently, it is not unreasonable to expect that the above
code change should work. However, when the author of <tt class=
"classname">arg::vector</tt> tries to achieve that, she discovers
that it is not quite possible within the standard.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e62" id="d0e62"></a>How does it go
wrong?</h2>
</div>
<p>It goes wrong because the above code uses <tt class=
"classname">std::swap&lt; arg::vector&lt;int&gt; &gt;</tt> - this
template is defined in such a way as to create a temporary copy and
exchange values by a series of assignment. The result is that the
client code ceases to be efficient and gives a far weaker exception
safety guarantee (probably the basic guarantee).</p>
<p>The <tt class="classname">std::swap</tt> template behaves
differently for the standard containers because it is overloaded in
such a way that <tt class="classname">std::swap&lt;
std::vector&lt;int&gt; &gt;</tt> calls <tt class=
"methodname">std::vector&lt;int&gt;::swap()</tt> and this gives the
no-throw guarantee.</p>
<p>Now the author of the <tt class="classname">arg::vector</tt>
template probably realised that a similar non-throwing swap
function was required - let us assume she has provided <tt class=
"methodname">arg::swap</tt> for this purpose. Those of you that
have heard of &quot;Koenig Lookup&quot; may wonder at this point why this
version of <tt class="methodname">swap</tt> isn't called. The
relevant passage is from <span class="emphasis"><em>3.4.2 -
Argument-dependent name lookup</em></span> paragraph 2: &quot;If the
ordinary unqualified lookup of the name finds the declaration of a
class member function, the associated namespaces and classes are
not considered.&quot;</p>
<p>This last clause is the reason we needed the using <tt class=
"classname">std::swap</tt> statement in the original code fragment
- if the class did not have a <tt class="methodname">swap</tt>
method it would work without. (Do not write and tell me that it
does not &quot;work without&quot; on your compiler - Visual C++ does not
support &quot;Koenig Lookup&quot; correctly.)</p>
<p>In that case you might ask &quot;why not overload the <tt class=
"classname">std::swap</tt> template?&quot; Because of another passage in
the standard <span class="emphasis"><em>17.4.3.1 - Reserved
names</em></span> paragraph 1 &quot;It is undefined for a C++ program to
add declarations or definitions to <tt class="literal">namespace
std</tt> or namespaces within <tt class="literal">namespace
std</tt> unless otherwise specified.&quot;</p>
<p>The same paragraph appears to allow some hope, because it
continues: &quot;A program may add template specializations for any
standard library template to <tt class="literal">namespace
std</tt>. Such a specialization (complete or partial) of a standard
library template results in undefined behavior unless the
declaration depends on a user-defined name of external linkage and
unless the specialization meets the standard library requirements
for the original template.&quot; This means that she could, in fact,
provide an explicit complete specialization of <tt class=
"classname">std::swap</tt> for <tt class=
"classname">arg::vector&lt;int&gt;</tt>. (Consequently, so long as
the library author or the user does this for every type on which
<tt class="classname">arg::vector&lt;int&gt;</tt> is instantiated
the problem is &quot;solved&quot;.)</p>
<p>What about &quot;partial specialization&quot; which was mentioned in the
above passage? Sorry, that only exists for class templates.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e133" id=
"d0e133"></a>Work-arounds</h2>
</div>
<p>Like many bugs there are ways to work around the problem:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Rely on remembering to add using <tt class=
"methodname">arg::swap</tt> to <tt class=
"methodname">client::swap</tt>.</p>
</li>
<li>
<p>Cultivate the habit of writing <tt class=
"methodname">xref.swap(that.xref)</tt>.</p>
</li>
<li>
<p>Exploit Koenig lookup as follows:</p>
<pre class="programlisting">
namespace {
  void indirect_swap(T&amp; l, T&amp; r) {
    using std::swap; // needed for
                     // fundamental types
    swap(l, r); // Now Koenig lookup can
                // find arg::swap
  }
}
void client::swap(client&amp; that) {
  indirect_swap(name, that.name);
  indirect_swap(xref, that.xref);
  indirect_swap(id, that.id);
}
</pre></li>
</ul>
</div>
<p>These, however, are not general solutions:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Fails if '<tt class="literal">lookup_table</tt>' is a template
parameter.</p>
</li>
<li>
<p>May fail if '<tt class="literal">lookup_table</tt>' is a
template parameter (i.e. may be a fundamental type) and reduces
code clarity.</p>
</li>
<li>
<p>Makes a mockery of the idea of having algorithms implemented as
standard functions in the library. (Note that nothing is specific
to <tt class="methodname">swap</tt> - it is just an example.)</p>
</li>
</ul>
</div>
<p>This last approach does justify the argument that the problem is
with unskilled use of the language. In practice, many users of C++
lack the skill to realise when this indirect approach to <tt class=
"literal">using std</tt> functions is necessary.</p>
<p>NONE of these work-arounds meet the need of a library author to
be able to produce containers that work correctly with the standard
algorithms. (E.g. since <tt class="classname">std::sort</tt> calls
<tt class="classname">std::swap</tt> versions of both algorithms
must be supplied.) Nor does it make it easy to write algorithms
that work with third party containers.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e193" id=
"d0e193"></a>Confession</h2>
</div>
<p>I strongly dislike relying on undefined behaviour but I do not
trust users of my code to implement the work-arounds described in
the last section. Consequently I have reluctantly adopted the
approach of overloading template functions in <tt class=
"literal">namespace std</tt>. This works on all implementations I
have encountered and has also been adopted by other library authors
(no, I will not name the guilty).</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e201" id="d0e201"></a>What will
happen next?</h2>
</div>
<p>There are two basic approaches to fixing this problem being
discussed within the committee. One (which brings other significant
benefits) is to introduce &quot;partial specialization&quot; of function
templates into the core language. The other is to relax the
restriction on overloading standard template functions. Neither of
these changes is likely to be in the forthcoming &quot;Technical
Corrigenda&quot;.</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
