    <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  :: Overloading on const is wrong</title>
        <link>https://members.accu.org/index.php/articles/605</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 #6 - Mar 1995</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/c177/">06</a>
<br />

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

                    -                        <a href="https://members.accu.org/index.php/articles/c65+177/">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;Overloading on const is wrong</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 27 March 1995 18:22:18 +01:00 or Mon, 27 March 1995 18:22:18 +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="d0e16" id="d0e16"></a></h2>
</div>
<p>As far as I can see from the current version of the Working
Paper on C++ the use of const in C++ programming is getting
increasingly perverted. Let me try to explain with the hope that
those responsible will reconsider.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a>The origins of
const</h2>
</div>
<p>As I understand it const first saw the light of day as a
mechanism to support passing by reference in a C++ environment. In
the days of pure C, parameters were either actual values or they
were pointers. Putting aside the argument as to whether passing an
address to a pointer is or is not a form of value passing, we
clearly had two distinct choices. We could pass a value and the
receiving function could do anything it liked with it without
damaging the original - rather like sending someone a fax. Or we
could pass a an address into a pointer and thereby allow the
original to be changed.</p>
<p>Apart from the eccentric form for providing arrays in C this
method always allowed the programmer to know if the information
made available to the function was 'read only' or not. C accepted
that this mechanism was inappropriate for large objects but simply
tolerated the problem. Handling arrays, unions and structs was not
part and parcel of much of the early programming done in C. It was
special enough so that most programmers learnt the special
conditions and took suitable care - well at least some did.</p>
<p>Almost immediately in C++ this dichotomy between 'read only' and
'writable' parameters became inadequate. C++ needed true
references, if for no other reason than to make user defined types
as easy to use as the built in ones. It was immediately obvious
that any reference mechanism would only be acceptable to the
majority of programmers if they could control access for
modification. const was invented. Once C saw the idea it realised
that it too could use const to support passing access to large data
elements. It developed the idea a little, added volatile and that
was it. Francis claims that C got it wrong because const does not
make values available at compile time. Actually I think C got it
right, const was meant to be a form of access control - you can
look but not touch.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e29" id="d0e29"></a>C++ develops
const</h2>
</div>
<p>You do not need much experience of C to realise that quite a lot
of conversion work can go on fixing the types of arguments to match
the types of the parameters they are passed to.</p>
<p>Remembering that const was introduced (or so I believe) to allow
references to do the same work as passing by value we have the
problem of fixing up type conversions between arguments and the
const references being bound to them. Lets look at a snippet of
code:</p>
<pre class="programlisting">
void fn(int i);
main(){
  float f;
  fn(f);
  return 0;
}
</pre>
<p>We know that value in f will be quietly converted to an int when
the call to fn() is made.</p>
<p>Now how about:</p>
<pre class="programlisting">
void fnp(const int * ip);
main(){
  float f;
  fnp(&amp;f);
  return 0;
}
</pre>
<p>And that should fail, because we cannot convert a float address
to an int*. Of course we can shoot our code in the foot with a cast
but that is a different issue.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e46" id="d0e46"></a>So now move to
C++</h2>
</div>
<pre class="programlisting">
void fnr(const int &amp; ir);
main(){
  float f;
  fnr(f);
  return 0;
}
</pre>
<p>Should this code compile? Well yes, because our intention when
we introduced const reference parameters was to allow a form of
reference use that would be just as safe as pass by value. As long
as the reference was only read and not written it should be
impossible to distinguish. There is a hidden consequence, the
compiler has to be able to create a temporary object of the
required type to bind to the reference, but otherwise fine.</p>
<p>Without the const qualification of the reference parameter the
compiler will reject the above code just as it would reject the
pointer equivalent because it is probably an error to write to a
temporary object.</p>
<p>Note that this actually makes const essential and not just an
optional extra. If we remove all uses of const from our code we are
going to find that some of our code will break because the compiler
will not allow a conversion of an argument type to match a
reference parameter type.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e57" id="d0e57"></a>The water gets
murky</h2>
</div>
<p>Unfortunately, language designers suffer from the problem of
generalising from the sane to the plain ridiculous. If the compiler
can make the above conversion for the purpose of passing an
argument to a reference parameter why stop there? Why not
allow:</p>
<pre class="programlisting">
float pi=3.1415926;
const int &amp; ipi=pi;
</pre>
<p>They had already discovered that allowing references in contexts
other than parameter passing could be useful. For example:</p>
<pre class="programlisting">
int array[101];
int &amp; median = array[50];
</pre>
<p>allowed naming individual elements of an array. Seduced by this
latter convenience they conclude that they will have to allow the
former insanity. If it got no worse than this, I guess we could
live with it. It isn't any more eccentric than many other elements
of both C and C++. However stay with me because it is about to get
much worse.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e70" id="d0e70"></a>Add some real
pollution</h2>
</div>
<p>For completely different reasons C++ introduced function
overloading. Bjarne Stroustrup tells us in his excellent book - The
Design and Evolution of C++ - that this feature was introduced to
support the need for alternative constructors. I am not convinced
because I can think of a couple of other viable methods but it
certainly is a fairly elegant solution to the problem of providing
multiple constructors.</p>
<p>Of course once we have function overloading for constructors,
what language designer could resist generalising them? It is
interesting to note that this wasn't quite a clear cut issue
because in the early days you had to explicitly specify overloading
with the keyword overload.</p>
<p>Now we have to set up rules to resolve overloading when some or
all parameters have to be converted. Clearly</p>
<pre class="programlisting">
void fn(int i);
void fn(const int &amp; i);
</pre>
<p>should not be distinguishable because the whole motive for
allowing const reference parameters was to provide an alternative
mechanism to passing by value. But what about:</p>
<pre class="programlisting">
void fn(int &amp; i);
void fn(const int &amp; i);
</pre>
<p>Think about it. Ask yourself if you can get any benefit from
such a set of overloaded functions that you could not get from:</p>
<pre class="programlisting">
void fn(int &amp; i);
void fnconst(const int &amp; i);
</pre>
<p>Well in the second case you will always have to say what you
mean. I think that is rather an advantage. Consider what a compiler
would do with the following code in each of the two cases
above.</p>
<pre class="programlisting">
main(){
  int i;
  const j=i;
  float f=2.4;
  fn(i);
  fn(j);  // error in case 2
  fn(f);  // error in case 2
  return 0;
}
</pre>
<p>Do the two errors that the second case would generate do
anything but improve the quality of the consequential code?</p>
<p>Unfortunately we do not always have the option of using a
different function name. Operators are rather attractive and we
certainly want to overload those. There is only one spelling for
any operator function and so all differences must be handled via
the overload mechanism. Consider the following:</p>
<pre class="programlisting">
class Array {
  int array[100];
  ... // other details
public:
  int &amp; operator [](int);
  const int &amp; operator [](int)const;
  ... // other details
};
</pre>
<p>Why two operator []()? Think about it. An explicit Array object
might be a const object (initialised by an appropriate constructor
but that is another problem). Even then we would want to be able to
write something like:</p>
<pre class="programlisting">
cout&lt;&lt;ao[10];
</pre>
<p>None-the-less, most of our array objects would be non-const and
so we would like to write code like:</p>
<pre class="programlisting">
ao[10]=5;
</pre>
<p>If we are going to have it both ways we need to overload
operator[]() on const.</p>
<p>Now my tale is complete. At each step we have done things that
are reasonable or attractive but the end result is mad to an extent
that most programmers will not even know which of two functions
will be called in each case. Note that the compiler does not need
to provide a temporary when converting to a base class because the
object really is an object of that type so:</p>
<pre class="programlisting">
void fn (D &amp;);
void fn (const D &amp;);
main (){
  B b;
  fn (b);
  return 0;
}
</pre>
<p>And now to decide which fn() is called, if any, you need to know
whether B is a base class of D or if B provides an explicit
conversion to D or neither.</p>
<p>However seductive the rationale for allowing overload resolution
based on const it is a poisoned gift, one we would be much better
off without.</p>
<p>const was and is a form of access control, for excellent reasons
we do not allow overload resolution based on other forms of access
and we should not do so for const.</p>
<p>Please, please, remove this excrescence from the language now
before it is too late. I do not believe that the convenience of
overloaded read-only and writable versions of operator[]() are
worth the cost. And apart from operators, I can get the
functionality without overloading on const.</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
