    <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  :: Student Code Critique Competition</title>
        <link>https://members.accu.org/index.php/journals/1236</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">CVu Journal Vol 15, #4 - Aug 2003 + Student Code Critiques from CVu journal.</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/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c107/">154</a>
                    (12)
<br />

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

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c184/">Journal Columns</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c183/">Code Critique</a>
                    (70)
<br />

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

                    -                        <a href="https://members.accu.org/index.php/journals/c107+183/">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;Student Code Critique Competition</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 07 August 2003 13:15:59 +01:00 or Thu, 07 August 2003 13:15:59 +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="d0e20" id="d0e20"></a>Student Code
Critique 22</h2>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e23" id="d0e23"></a>The Code</h3>
</div>
<p>Please look at the following code that is just playing with
container of objects.</p>
<pre class="programlisting">
#include&lt;iostream&gt;
#include&lt;fstream&gt;
#include&lt;vector&gt;
using namespace std;

class A {
public:
  A(int p1= 0) : x(p1) { cout&lt;&lt;&quot;CTOR&quot;&lt;&lt;endl; }
  A(const A&amp; a) {
    x = a.x;
    cout&lt;&lt;&quot;COPY CTOR&quot;&lt;&lt;endl;
  }
  ~A() {
    cout &lt;&lt; &quot;DTOR: address = &quot; &lt;&lt; (long)this &lt;&lt;endl;
  }
  friend ostream&amp;
            operator&lt;&lt;(ostream&amp; out, const A&amp; obj);
private:
  int x;
};
ostream&amp; operator&lt;&lt; (ostream&amp; out, const A&amp; obj) {
  out &lt;&lt; &quot;x = &quot;&lt;&lt;(obj.x)&lt;&lt;endl;
  return out;
}

int main() {
  vector&lt;A&gt; v;
  // Be inefficient, not production code
  for(int i=0; i&lt;3; i++)
    v.push_back(A(i));
  // Lo behold, container of objects
  copy(v.begin(), v.end(),
             ostream_iterator&lt;A&gt;(cout, &quot;&quot;));
  cout &lt;&lt; endl;
  A * pa = &amp;(v.back());
  // pa points to address of reference
  // to the last element
  cout &lt;&lt; (*pa); // info
  cout &lt;&lt; &quot;pa = &quot;
       &lt;&lt; (long)pa &lt;&lt; endl;                         // address
  cout &lt;&lt; &quot;call pop_back()&quot; &lt;&lt;endl;
  v.pop_back();                                     // Line A
  // destructor WILL destroy last element
  // Now pa points to deleted memory, should crash
  cout &lt;&lt; (*pa);                                    // Line B
  cout &lt;&lt; &quot;pa = &quot; &lt;&lt; (long)pa &lt;&lt; endl; // address
  delete pa;                                        // Line C
  return 0;
}
</pre>
<p>Lines A and C delete the same memory, which shouldn't be
allowed. But program runs fine allowing dereferencing at line B.
Why?</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e32" id="d0e32"></a>From Matthew
Towler &lt;<tt class="email">&lt;<a href=
"mailto:towler@ccdc.cam.ac.uk">towler@ccdc.cam.ac.uk</a>&gt;</tt>&gt;</h3>
</div>
<p>There are a few misconceptions that lead to the behaviour seen,
and a number of small style issues in this code. I will begin with
the more important, larger issues.</p>
<p>The first comment in <tt class="function">main</tt> &quot;be
inefficient, not production code&quot; implies that test code should be
deliberately inefficient, and on changing to production code
everything should be rewritten with efficiency first. Code should
be written to be simple and easily understood first, and then
optimised if this is shown by measurement to be necessary.</p>
<p>The comment on lines 10 and 11 of main is misleading. Taking the
address of a reference yields a pointer to the referenced item,
rather than the &quot;address of reference&quot;, which has no meaning in
C++. A more accurate comment would be</p>
<pre class="programlisting">
// pa points to the last element
</pre>
<p>The next issue is on line A, but first an aside.</p>
<p>Objects are created in two stages, first raw memory is
allocated, either on the stack or the heap (with <tt class=
"literal">new</tt>) - at this point it is just a collection of
bytes. An object is then constructed into this memory by a
constructor - this initialises the memory to create an object of
the desired type.</p>
<p>Destroying objects is the reverse; first a destructor removes
the object from the memory leaving again a block of raw bytes,
which are then returned to the system. <tt class=
"literal">delete</tt>ing a pointer performs both of these steps,
but note that the steps do not have to be combined.</p>
<p>the object's destructor, but does not imply releasing the
memory. This last stage depends on the implementation of the
container, and is not normally of concern to the programmer. During
this call either the container reallocates its storage, leaving
<tt class="varname">pa</tt> pointing at now unused memory; or (and
most likely given the observed behaviour) the memory is unaltered,
so <tt class="varname">pa</tt> now points at uninitialised memory.
Note that for vectors, adding or removing elements invalidates all
interators and pointers into the container. When using any
container you should be aware of what operations invalidate
iterators.</p>
<p>This means the second line of the comment after line A is
incorrect, the memory may or may not have been deleted.</p>
<p>Line B is then accessing uninitialised memory, which will give
what is referred to as 'undefined behaviour'. Undefined means
exactly that, it could do anything ranging from nothing, to (as
some are fond of stating) reformatting your hard disk, and anything
in between. Sometimes the code will crash (usually with a core dump
or halt in the debugger) but it is wrong to expect a noticeable
failure.</p>
<p>The observed behaviour suggests the uninitialised memory that
<tt class="varname">pa</tt> points to was not altered by the
destruction, so the access to the memory works as if the object
still existed - perfectly in line with 'undefined behaviour'</p>
<p>The next line works correctly as <tt class="varname">pa</tt> has
not been altered.</p>
<p>Finally line C attempts to destroy the object referred to by
<tt class="varname">pa</tt>. This will first call the destructor,
which will do something undefined (in this case the trace output
makes it appear to work); it then calls operator <tt class=
"literal">delete</tt>. Deleting a pointer not allocated with
<tt class="literal">new</tt> (such as <tt class="varname">pa</tt>)
results in further undefined behaviour. In this case the particular
implementation of delete presumably realises this and does nothing
observable.</p>
<p>As regards the programmer's perceived problem - deleting memory
already deleted has undefined behaviour, there is nothing in the
language that detects and disallows such attempts.</p>
<p>Fundamentally, the programmer needs to understand that a
<tt class="classname">vector&lt;A&gt;</tt> is storing the
<span class="type">A</span> by value i.e. by storing copies of
<span class="type">A</span> objects. Not by allocating <span class=
"type">A</span>s on the heap. The container deals with the memory
management aspects automatically.</p>
<p>Now the smaller coding style issues, IMHO all are generally
considered bad practice and can either be taken as read or the
explanations found elsewhere.</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Use of a default value in the constructor argument rather than a
separate default constructor</p>
</li>
<li>
<p>Lack of <tt class="literal">explicit</tt> keyword on a single
argument constructor, especially one taking an <tt class=
"literal">int</tt>.</p>
</li>
<li>
<p>Use of direct initialisation in <span class="type">A</span>'s
copy constructor, rather than an initialiser list.</p>
</li>
<li>
<p>C style cast of <tt class="literal">this</tt> pointer to
<tt class="literal">long</tt> when outputting. This is not
portable, and is unnecessary as there will be a system supplied
output operator for pointers.</p>
</li>
<li>
<p>Use of <tt class="literal">endl</tt> everywhere rather than
simply <tt class="literal">'\n'</tt>, this is not crucial for test
code, but it is a bad habit to get in to.</p>
</li>
<li>
<p><span class="type">A</span> has a copy constructor but no
assignment operator, these functions should always appear in
pairs.</p>
</li>
<li>
<p>The second comment in <tt class="function">main</tt> does not
add anything to the understanding of the code. Comments should only
be used to explain the higher level intent of the code or unusual
or difficult to understand passages.</p>
</li>
<li>
<p>Use of <tt class="literal">i++</tt> rather than the preferred
<tt class="literal">++i</tt> in a loop, this is not so important
for <tt class="literal">int</tt>s but it is a good habit to
develop.</p>
</li>
<li>
<p>It is worth making use of the separator argument in <span class=
"type">ostream_iterator</span> (<tt class="literal">&quot;&quot;</tt> does
nothing) otherwise the output runs together e.g. 3 elements with
values 12, 3, 4 would be output as &quot;1234&quot;.</p>
</li>
<li>
<p>Calling code which might throw an exception (such as output
operators) in a destructor is dangerous, it should be surrounded by
a <tt class="literal">try..catch</tt> block to stop any exceptions
escaping.</p>
</li>
</ul>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e190" id="d0e190"></a>From Ruurd Pels
&lt;<tt class="email">&lt;<a href=
"mailto:ruurd@tiscali.nl">ruurd@tiscali.nl</a>&gt;</tt>&gt;</h3>
</div>
<p>Oh, well. I might as well try this. Here it goes.</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Layout</p>
<p>Apart from the obvious editing to fit the source in the columns,
I would like to implore anyone that source code is a document. And
documents should be readable, preferably to others. The code under
scrutiny is sloppy in layout and lacks to convey what the intention
is. More tongue-in-cheek, I think we can leave the time that there
were language implementations that only allowed one-character
variable names safely behind us. In my opinion, verbosity is not a
bad thing, on the other hand, sometimes I myself go overboard.</p>
<p>A few style pointers are in order:</p>
<div class="orderedlist">
<ol type="a">
<li>
<p>Use type names and variable names that make clear what they
represent, so, here, <tt class="literal">class Integer</tt> instead
of <tt class="literal">class A</tt>.</p>
</li>
<li>
<p>If code is documented inline, I like to see the comment indented
at the same level as the code that follows. Not doing so tends to
blur the outline of the code and makes it harder to read.</p>
</li>
<li>
<p>Last, but not least, some general remarks regarding the purpose
of the program would be in order.</p>
</li>
</ol>
</div>
</li>
<li>
<p>Idiom.</p>
<p>In 'Advanced C++ Styles And Idioms', Coplien tells us that if
and when we do not intend to create types that are second grade
citizens, we must adhere to the 'Orthodox Canonical Form'. This
means that a default constructor, a copy constructor, an assignment
operator and a destructor must be implemented. It is my tendency to
explicitly specify all of them instead of relying on the compiler
to generate the default ones for me, so I added the assignment
operator. As for the destructor, I almost invariably make them
virtual, just to prevent rude surprises if I derive another class
from a class I created. Only in very special circumstances and duly
commented in the source code I use a static destructor.</p>
<p>The main function usually is defined as:</p>
<pre class="programlisting">
int main(int argc, char* argv[])
</pre>
<p>but when not using those arguments, I would prefer to see:</p>
<pre class="programlisting">
int main(int, char*[])
</pre>
<p>but certainly not:</p>
<pre class="programlisting">
#pragma argsused
int main(int argc, char* argv[])
</pre>
<p>In the same vein, returning 0 at the end of <tt class=
"function">main</tt> should be replaced with the more portable
<tt class="literal">EXIT_SUCCESS</tt>.</p>
<p class="c2"><span class="remark">[Please note that I would argue
with almost all the above. Do not provide a virtual destructor
unless you intend the class to be a base class - and think very
carefully before deriving from a non-abstract base. I would prefer
the signature <tt class="literal">int main()</tt> if command line
arguments are not used because it is the long hallowed idiom to
express that intent and <tt class="literal">return 0</tt> is just
as portable as <tt class="literal">return EXIT_SUCCESS</tt>.
FG]</span></p>
<p>With respect to the <span class="type">ostream</span> friend, I
have a few remarks. Even in the eye of friendship, I tend to use
accessor methods to obtain the inner value from the object to be
streamed, but there is another little idiom I would like to present
in this matter. If <tt class="literal">class A</tt> would be the
base class for other classes, it is beneficial to separate the
actual streaming from the body of the friend function and add that
functionality to a <tt class="literal">protected virtual
streamOn</tt> method <i><span class="remark">[but why not make it
virtual? FG]</span></i> This makes the task of streaming much
easier, because it is only necessary to overload the streamOn
function in derived classes instead of rewriting the ostream friend
boilerplate over and over again, so:</p>
<pre class="programlisting">
void Integer::streamOn(ostream&amp; ostr) {
  ostr &lt;&lt; getValue();
}
ostream&amp; operator&lt;&lt;(ostream&amp; ostr,
                    Integer const &amp; obj) {
  obj.streamOn(ostr);
  return ostr;
}
</pre>
<p>Last but not least, if streaming an object to an <span class=
"type">ostream</span>, adding text or an end-of-line to the
streaming operation is generally a bad plan, because the user of
the class then cannot decide how he will do output formatting.
Every time he uses the streaming friend, he gets the text and the
newline 'for free', possibly at a time that is inconvenient to him.
Furthermore, it is very easy to forget to consume the text and the
newline when at a certain time a corresponding input stream
operator is written. Realizing that an <span class=
"type">ostream</span> does not necessarily mean that the content of
an object is printed on a console is important in this matter.</p>
<p>In the <tt class="function">main</tt> function, a template is
instantiated. I know that this is trivial code in some respect, but
I prefer to use <tt class="literal">typedef</tt>s to create 'new'
types based on templates, and while I am at it, <tt class=
"literal">typedef</tt> the iterators as well. So instead of:</p>
<pre class="programlisting">
vector&lt;A&gt; v;
</pre>
<p>I would prefer to see:</p>
<pre class="programlisting">
typedef vector&lt;Integer&gt; IntegerVector;
typedef IntegerVector::iterator
                       IntegerVectorIterator;
typedef IntegerVector::const_iterator
                       IntegerVectorConstIterator;
</pre>
<p class="c2"><span class="remark">[If you are going to use those
names I can see very little benefit from using typedefs. In my
opinion a <tt class="literal">typedef</tt> should be used to create
a more descriptive name for a type. Yours do not do that so skip
them. FG]</span></p>
<p>and subsequently:</p>
<pre class="programlisting">
IntegerVector integerVector;
</pre>
<p>In a more general case, this even collapses to for example:</p>
<pre class="programlisting">
typedef vector&lt;Rule&gt; Rules;
typedef Rules::iterator RulesIterator;
typedef Rules::const_iterator
               RulesConstIterator;
</pre>
<p class="c2"><span class="remark">[Now I agree about the first,
but again I think the other two add nothing. FG]</span></p>
<p>in which case it is quite easy to change the container type to
something different, for example, if rules are all of a sudden
uniquely identified, into:</p>
<pre class="programlisting">
typedef set&lt;Rule&gt; Rules;
</pre>
<p>without having to change much in any code using the Rules
type.</p>
<p class="c2"><span class="remark">[and that is a good reason for
the first <tt class="literal">typedef</tt> but not for the
<tt class="literal">typedef</tt> applied to the iterators.
FG]</span></p>
<p>Call them style idiosyncracies, I have developed some I guess. I
have the tendency to use 'that' for the parameter name if I need to
refer to another value of the same type, at least in the copy
constructors and the assignment operator. Also, in streaming
friends, I tend to name the <tt class="literal">ostream&amp;</tt>
parameter as <tt class="literal">ostr</tt>.</p>
<p class="c2"><span class="remark">[Yes we all have our personal
styles but we should always examine naming conventions and ask if
they add to the readability of the code. FG]</span></p>
</li>
<li>
<p>Intent.</p>
<p>From what I gather from the source code, this is an exercise in
reconnoitring the innards of a vector and the memory allocation
strategies of the underlying operating system. I don't have a
problem with stretching computers and operating systems. However,
this type of code could be an indication that the student does not
properly understand the true nature of object oriented programming
at large or STL container classes in particular. Halfway through
the main function the line between the concept of container classes
and the technique employed by it is crossed. At a certain point in
time, he seems to want to treat the vector container as an array of
<tt class="classname">Integer</tt> objects, misusing the fact that
<tt class="methodname">vector::back()</tt> returns a <tt class=
"literal">const</tt> reference to the object in the container in
order to create a pointer to that object.</p>
<p>At a certain point, the student wants to inspect the address of
the object and uses a cast to output the address pointed to by the
pointer to A. The cast is superfluous, and also wrong. If the
intent was to convert the address to an integer number, on 32-bit
architectures at least the cast would have to be towards an
<tt class="literal">unsigned long</tt>, but since the cast is
supefluous, simply streaming out the pointer would have yielded the
address pointed to in hexadecimal notation. The simple:</p>
<pre class="programlisting">
cout &lt;&lt; pa &lt;&lt; endl;
</pre>
<p>would have sufficed. This leads me to believe that the student
should again review how pointers are treated in C++, especially in
the face of passing them to an <span class="type">ostream</span>
object.</p>
<p>The statement:</p>
<pre class="programlisting">
A* pa = &amp;(v.back());
</pre>
<p>leads me to believe that the student must be taught the concept
of ownership. It should be made clear to him that an STL container
has ownership of the objects stored in it and that access to the
elements of the container should be done through the methods the
container provides. Awareness of ownership problems will make him a
better software engineer.</p>
<p>Last but not least, the question why the program does not crash
on line B and why the double deletion seems to be allowed. The case
probably is that a vector allocates an array of objects to
accommodate its elements. This means that <tt class=
"methodname">vector&lt;T&gt;::pop_back()</tt> indeed calls the
destructor of the element, but does not remove the storage space
associated with it. In combination with the fact that we are
dealing with a very simple class stored in the container, this
could mean that even if the destructor is called, the memory is
still there and is still used by the container. If the stored
object was more complex, for example referring to dynamically
allocated memory, the dereferencing probably would have gone awry
as well as the double deletion of the object. For what it is worth,
I tried this under gcc 3.2, and the second time the destructor is
called through delete pa it is not even executed.</p>
</li>
<li>
<p>Finally.</p>
<p>I sort of tried to recreate the same problem here. The main code
is not very much better in terms of properly handling the
container, however, I adjusted a number of stylish and idiomatic
flaws:</p>
<pre class="programlisting">
// Student Code Critique 22, Critiqued
#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;vector&gt;
using namespace std;

class Integer {
public:
  Integer(int theValue = 0);
  Integer(const Integer&amp; that);
  Integer&amp; operator=(const Integer&amp; that);
  virtual ~Integer();
  int getValue() const;
  friend ostream&amp; operator&lt;&lt;(ostream&amp; ostr,
                             const Integer&amp; obj);
protected:
  virtual void streamOn(ostream&amp; ostr) const;
private:
  int value;
};

Integer::Integer(int theValue)
    : value(theValue){
  cout &lt;&lt; &quot;ctor(&quot; &lt;&lt; value &lt;&lt; &quot;)&quot; &lt;&lt; endl;
}

Integer::Integer(const Integer&amp; that)
    : value(that.value){
  cout &lt;&lt; &quot;cctr(&quot; &lt;&lt; value &lt;&lt; &quot;)&quot; &lt;&lt; endl;
}

Integer&amp; Integer::operator=(const
    Integer&amp; that){
  value = that.value;
  cout &lt;&lt; &quot;op=(&quot; &lt;&lt; value
       &lt;&lt; &quot;)&quot; &lt;&lt; endl;
  return *this;
}

Integer::~Integer() {
  cout &lt;&lt; &quot;dtor(&quot; &lt;&lt; this
       &lt;&lt; &quot;)&quot; &lt;&lt; endl;
}

int Integer::getValue() const {
  return value;
}

void Integer::streamOn(ostream&amp; ostr) const {
  ostr &lt;&lt; getValue();
}

ostream&amp; operator&lt;&lt;(ostream&amp; ostr,
    const Integer&amp; obj) {
  obj.printOn(ostr);
  return ostr;
}

typedef vector&lt;Integer&gt; IntegerVector;
typedef IntegerVector::iterator
IntegerVectorIterator;
typedef IntegerVector::const_iterator
IntegerVectorConstIterator;

int main() {
  IntegerVector integerVector;
  for(int i = 0; i &lt; 3; i++)
    integerVector.push_back(Integer(i));
  Integer* integerpointer
    = &amp;(integerVector.back());
  cout &lt;&lt; &quot;integer value = &quot;
       &lt;&lt; *integerpointer &lt;&lt; endl;
  cout &lt;&lt; &quot;integer address = &quot;
       &lt;&lt; integerpointer &lt;&lt; endl;
  cout &lt;&lt; &quot;call integerVector.pop_back()&quot;
       &lt;&lt; endl;
  integerVector.pop_back();
  cout &lt;&lt; &quot;integer value = &quot;
       &lt;&lt; *integerpointer &lt;&lt; endl;
  cout &lt;&lt; &quot;integer address = &quot;
       &lt;&lt; integerpointer &lt;&lt; endl;
  delete integerpointer;
  return EXIT_SUCCESS;
}
</pre>
<p class="c2"><span class="remark">[I made some minor corrections
to Ruurd's English and added rather more comments than I normally
do somewhat in the style I would use were I conducting a seminar. I
am aware that naming style is both individual and varies from one
national group to another. However names should add value and, in
my opinion, overly long names work to destroy the shape of code. It
is no accident that mathematicians prefer very short names. The
skill is in finding the point of balance.</span></p>
<p class="c2"><span class="remark">My final point is that while I
agree with the provision of streaming functionality through a
member function, I would make it <tt class="literal">public</tt>
and abandon the <tt class="literal">friend</tt> declaration of the
streaming <tt class="function">operator &lt;&lt;</tt>. There is
still a tendency to overuse <tt class="literal">friend</tt>
declarations. FG]</span></p>
</li>
</ol>
</div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e406" id="d0e406"></a>The Winner of
SCC 22</h3>
</div>
<p>The editor's choice is: <span class="bold"><b>Matthew
Towler</b></span></p>
<p>Please email <tt class="email">&lt;<a href=
"mailto:francis@robinton.demon.co.uk">francis@robinton.demon.co.uk</a>&gt;</tt>
to arrange for your prize.</p>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e418" id="d0e418"></a>Student Code
Critique 23</h2>
</div>
<p>(Submissions to <tt class="email">&lt;<a href=
"mailto:francis@robinton.demon.co.uk">francis@robinton.demon.co.uk</a>&gt;</tt>
by Sept. 6th)</p>
<p class="c2"><span class="remark">It is very easy for more
experienced programmers to forget how completely confused a novice
can become when asked to write a program for some simple task. I
have picked the following out of my slush pile because it
illustrates the problem at many different levels. It starts with
what is a clear confusion (if you can have such an oxymoron) about
the problem itself and then goes downhill from there.</span></p>
<p class="c2"><span class="remark">What would you do to help this
student with his programming? Note that this time the student knows
enough about C++ to write a suitable program, so the problem is in
the mind to the extent that I think he is even confused by what is
needed as output.</span></p>
<p>I am working on a program that will tell someone how old they
are in years, days and months. I.e. You are 27 years, 200 months,
and 1500 days old.</p>
<pre class="programlisting">
#include &lt;iostream&gt;
using namespace std;
void main() {
  int currentyear = 2003;
  int dob = 0;
  int result = 0;
  int day = 0;
  int month = 0;
  cout &lt;&lt; &quot;Enter your year of birth: &quot;;
  cin &gt;&gt; dob;
  result = dob - 2003;
  cout &lt;&lt; &quot;You are &quot; &lt;&lt; result
       &lt;&lt; &quot; years old&quot; &lt;&lt; endl;
  cout &lt;&lt; &quot;Enther you month of birth: &quot;;
  cin &gt;&gt; month;
  for(result=0; result &lt;=12; result++)
    if(result &lt;= 12) result = month+12;
  cout &lt;&lt; &quot;You are &quot; &lt;&lt; result
       &lt;&lt; &quot; months old&quot;&lt;&lt;endl;
  cout &lt;&lt; &quot;Enter you day of birth: &quot;;
  cin &gt;&gt; day;
  for(result=0; result &lt;= 365; result++)
    if(result&lt;=365) result = day+365;
  cout &lt;&lt;&quot;You are &quot; &lt;&lt; result
       &lt;&lt; &quot; days old&quot;&lt;&lt;endl;
}
</pre>
<i><span class="remark">Of course remember to comment on the
program defects but your main focus should be how to explain the
need for clear thought when producing a solution.</span></i></div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
