    <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 35</title>
        <link>https://members.accu.org/index.php/journals/829</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 17, #4 - Aug 2005 + 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/c95/">174</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/c95-183/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c95+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 35</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 August 2005 05:00:00 +01:00 or Wed, 03 August 2005 05:00:00 +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></h2>
</div>
<p><span class="bold"><b>Prizes provided by Blackwells Bookshops
&amp; Addison-Wesley</b></span></p>
<p class="c3"><span class="remark">Please note that participation
in this competition is open to all members. The title reflects the
fact that the code used is normally provided by a student as part
of their course work.</span></p>
<p class="c3"><span class="remark">This item is part of the
Dialogue section of C Vu, which is intended to designate it as an
item where reader interaction is particularly important. Readers'
comments and criticisms of published entries are always welcome, as
are possible samples.</span></p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e32" id="d0e32"></a>Before We
Start</h2>
</div>
<p>Remember that you can get the current problem set in the ACCU
website (<a href="http://www.accu.org/journals/" target=
"_top">http://www.accu.org/journals/</a>). This is aimed at people
living overseas who get the magazine much later than members in the
UK and Europe.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e40" id="d0e40"></a>Student Code
Critique 34 Entries</h2>
</div>
<div class="blockquote">
<blockquote class="blockquote">
<p>I send an unsigned char called tipus which is meant to be some
hex number from 0x00 to 0xff and which should decide the string to
be returned...</p>
<p>If the unsigned int called <tt class="varname">valor</tt> I send
is above 0xA000 I use the struct <span class=
"structname">decidetest</span> to send a string back, else, I send
a string selected from the struct <span class=
"structname">decide</span>.</p>
<p>If no substitution is made, then the string returned is always a
space in html... <tt class="literal">&amp;nbsp;</tt></p>
<p>For some reason I always get the <tt class="type">static
char</tt> <tt class="varname">escape</tt> string returned... any
idea? (the function compiles all right...)</p>
<pre class="programlisting">
char* Detect_type(unsigned char tipus, unsigned int valor)
{
int i;
static char escape[16] = &quot;&amp;nbsp; &quot;;
static struct decide {
unsigned num;
char *string;
} cadena [] = {
         {0x00, &quot;Sobre V PK &quot;},
         {0x02, &quot;Sobre V RMS &quot;},
         {0x0E, &quot;--Power OFF--&quot;},
         {0x10, &quot;--Power ON--&quot;},
         {0xff, &quot; &quot;},
};

static struct decidetest {
unsigned numero;
unsigned char num;
char *string;
} cadenatest [] = {
         {0x00, &quot;Sobre V PK Test&quot;},
         {0x02, &quot;Sobre V RMS Test&quot;},
         {0x0E, &quot;--Power OFF--&quot;},
         {0x10, &quot;--Power ON--&quot;},
         {0xff, &quot; &quot;},
};

if (valor &gt;= 0xA000)
  {
    for(i = 0; i &lt; sizeof(cadenatest) /
        sizeof(cadenatest[0]); i++)
    if(cadenatest[i].num == tipus)
      return cadenatest[i].string;
  }
else
  {
    for(i = 0; i &lt; sizeof(cadena) /
        sizeof(cadena[0]); i++)
    if(cadena[i].num == tipus)
      return cadena[i].string;
  }

return (escape);
}
</pre></blockquote>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e70" id="d0e70"></a>From Roger Leigh
<tt class="email">&lt;<a href=
"mailto:rleigh@whinlatter.ukfsn.org">rleigh@whinlatter.ukfsn.org</a>&gt;</tt></h3>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e75" id="d0e75"></a>The Initial
Problem</h4>
</div>
<p>We are told the function &quot;compiles all right&quot;. This is not
true:</p>
<pre class="screen">
$ gcc -c orig.c
orig.c: In function 'Detect_type':
orig.c:22: warning: initialization makes integer from pointer without a cast
orig.c:22: error: initializer element is not computable at load time
orig.c:22: error: (near initialization for 'cadenatest[0].num')
orig.c:22: error: initializer element is not constant
orig.c:22: error: (near initialization for 'cadenatest[0]')
</pre>
<p>The following changes were made to correct various problems with
the code. The code is compliant with the ISO C99 standard.</p>
<p>Looking at the source code, we see that <span class=
"structname">struct decidetest</span> has three members, of which
only two are used. Comparing with <span class="structname">struct
decide</span>, <i class="structfield"><tt>numero</tt></i> looks out
of place. If this is removed, the function compiles, and appears to
work as intended (I added a simple test program to test each case,
including failure). It's always a good idea to do this when writing
code: when making the following changes I could check for breakage
after each change.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e96" id="d0e96"></a>Cosmetic
Problems</h4>
</div>
<p><tt class="function">Detect_type</tt> is an unusual name. Think
about why you are using a particular naming scheme. Common types
are <tt class="literal">CamelCaseNames</tt> and <tt class=
"literal">lower_case_underscored</tt>. As an example, I usually use
camel case for structure and class names, and lower case for all
function names, methods and variables. The aim of the
capitalisation and underscoring is to separate individual words to
give readable and meaningful identifiers. Often there will be a
common suffix within a particular program or library, a
&quot;namespace&quot;. I renamed the function to <tt class=
"function">detect_type</tt>.</p>
<p>Your indentation was mostly acceptable, but indentation
following curly brackets varied depending on whether they were
enclosing the function body or any other use. I re-indented it
using Emacs.</p>
<p>The identifiers used, <tt class="varname">tipus</tt> and
<tt class="varname">valor</tt>, do not appear to have any
meaningful bearing on their use within the function. It is
important to use identifiers that convey meaning. I renamed
<tt class="varname">tipus</tt> to <tt class=
"varname">value</tt>.</p>
<p><tt class="varname">valor</tt> is an unsigned integer, yet is
used in a Boolean manner. Quite what the special significance of
0xA000 is is not at all clear. This sort of undocumented magic
inside functions will only cause maintenance problems later: keep
this localised to where it actually means something. Presumably
this has meaning elsewhere in your code, but here a simple
true/false value is sufficient. I replaced <tt class=
"type">unsigned int</tt> <tt class="varname">valor</tt> with
<tt class="type">bool</tt> <tt class="varname">test</tt>. The
caller can simply use <tt class="literal">(valor &gt;= 0xA000)</tt>
to achieve the same behaviour.</p>
<p><tt class="varname">escape</tt> is only used once. Why not
eliminate it entirely?</p>
<p>The return value is in parentheses. <tt class=
"literal">return</tt> is a keyword, not a function, making this
unnecessary.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e154" id="d0e154"></a>struct
decide</h4>
</div>
<p>After removing <i class="structfield"><tt>numero</tt></i> from
<span class="structname">struct decidetest</span>, <span class=
"structname">struct decide</span> and <span class=
"structname">struct decidetest</span> are now identical. There is
no need to define two identical structures, so I removed
<span class="structname">struct decidetest</span>.</p>
<p>The <i class="structfield"><tt>num</tt></i> member of
<span class="structname">struct decide</span> is an <tt class=
"type">unsigned int</tt>, but <tt class="varname">valor</tt> (now
<tt class="varname">value</tt>) is an <tt class="type">unsigned
char</tt>. There's no need for the extra size, so I changed it to
<tt class="type">unsigned char</tt>. Because it's used as a value
rather than a character, I then changed all the instances of
<tt class="type">unsigned char</tt> to <tt class=
"type">uint8_t</tt> from <tt class=
"filename">&lt;stdint.h&gt;</tt>, to better reflect its use as a
number rather than a character.</p>
<p>The &quot;string&quot; member of <span class="structname">struct
decide</span> is not <tt class="literal">const</tt>, but it only
ever contains string literals. The function also returns a
non-<tt class="literal">const</tt> pointer to it. I made all
character data <tt class="literal">const</tt>, and made the return
type <tt class="literal">const</tt> as well. <tt class=
"literal">const</tt> correctness prevents accidental modifications,
and therefore makes your code more robust.</p>
<p>The initialisers are quite simple, because there are only two
members. You might want to consider using C99 named initialisers
for bigger structures, which significantly improves readability and
protects against accidentally missing out a member (as we saw in
the case of <span class="structname">struct decidetest</span>).</p>
<p>The last member of both <tt class="varname">cadena</tt> and
<tt class="varname">cadenatest</tt> is followed by a trailing
comma. Some compilers don't like this.</p>
<p>Quite what the meaning of the &quot;magic&quot; constants 0x00, 0x02,
0x0E, 0x10 and 0xFF are is not apparent. If their only purpose is
to be unique and in a certain order, using an <tt class=
"literal">enum</tt> would make the code cleaner and more
maintainable. I haven't changed this because I can't be certain of
breaking other code.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e244" id="d0e244"></a>Strings</h4>
</div>
<p>The string <tt class="varname">escape</tt> and most of the other
string literals are of length 16. Is this a requirement? If so, the
type of &quot;string&quot; in <span class="structname">struct decide</span>
should also be <tt class="type">char [16]</tt>, and all of the
strings starting with &quot;-Power&quot; are too short. If it's not a
requirement, just make them all of type <tt class="type">const char
*</tt> (field widths may be specified with a <tt class=
"function">printf</tt> format string, illustrated in the test
code). I made this change, because hard-coded string length
limitations are rarely used in modern code.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e264" id="d0e264"></a>Eliminating
Redundancy</h4>
</div>
<p>The for loop that iterates through the various values is
repeated twice for both <tt class="varname">cadena</tt> and
<tt class="varname">cadenatest</tt>. This can be eliminated by
using a simple pointer. This also required adding an extra
<tt class="literal">NULL</tt> element to the end of each array.
This also allowed <tt class="varname">i</tt> to be removed.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e281" id="d0e281"></a>Amended
Code</h4>
</div>
<p>This is the result of making the above changes. I hope you can
see that a few simple changes have made the code much more readable
and easy to understand. It's not that the code is doing anything
very different, but that the intentions of the programmer are made
clear because the structure of the code makes this obvious. The
code is also simpler, which makes it easier to understand.</p>
<p>Also note the comments preceding the function. It's important to
document the public interfaces of our code, and there are many
tools available which can extract the comments from the code and
produce full API references.</p>
<pre class="programlisting">
#include &lt;stdbool.h&gt;
#include &lt;stdint.h&gt;
#include &lt;stdlib.h&gt;

/**
* detect_type:
* @value: the value to detect the type of
* @test: true if this is a test,
* otherwise false
*
* Detect a type.
*
* Returns a string describing the type of
* @value, or &quot;&amp;nbsp;&quot; if @value was not
* found. The string must not be freed.
*/
const char *
detect_type (uint8_t value,
       bool test)
{
  struct decide
  {
    uint8_t num;
    const char *string;
  };

  static const struct decide cadena[] =
    {
      {0x00, &quot;Sobre V PK&quot;},
      {0x02, &quot;Sobre V RMS&quot;},
      {0x0E, &quot;-Power OFF-&quot;},
      {0x10, &quot;-Power ON-&quot;},
      {0xff, &quot;&quot;},
      {0x00, NULL}
    };

  static const struct decide cadenatest[] =
    {
      {0x00, &quot;Sobre V PK Test&quot;},
      {0x02, &quot;Sobre V RMS Test&quot;},
      {0x0E, &quot;-Power OFF-&quot;},
      {0x10, &quot;-Power ON-&quot;},
      {0xFF, &quot;&quot;},
      {0x00, NULL}
    };

  for (const struct decide *iter =
       (test == true) ? &amp;cadenatest[0] :
                        &amp;cadena[0];
       iter-&gt;string != NULL;
       ++iter)
    {
      if (iter-&gt;num == value)
        return iter-&gt;string;
    }

  return &quot;&amp;nbsp;&quot;;
}

// A simple test case
#include &lt;stdio.h&gt;

int
main (void)
{
  printf(&quot;Value Test String\n&quot;);
  printf(&quot;--- --- -----------\n&quot;);
  printf(&quot;0x00, false: '%-20s'\n&quot;, detect_type(0x00, false));
  printf(&quot;0x02, false: '%-20s'\n&quot;, detect_type(0x02, false));
  printf(&quot;0x0A, false: '%-20s'\n&quot;, detect_type(0x0A, false));
  printf(&quot;0x0E, false: '%-20s'\n&quot;, detect_type(0x0E, false));
  printf(&quot;0x10, false: '%-20s'\n&quot;, detect_type(0x10, false));
  printf(&quot;0xFF, false: '%-20s'\n&quot;, detect_type(0xFF, false));
  printf(&quot;0x00, true: '%-20s'\n&quot;, detect_type(0x00, true));
  printf(&quot;0x02, true: '%-20s'\n&quot;, detect_type(0x02, true));
  printf(&quot;0x0A, true: '%-20s'\n&quot;, detect_type(0x0A, true));
  printf(&quot;0x0E, true: '%-20s'\n&quot;, detect_type(0x0E, true));
  printf(&quot;0x10, true: '%-20s'\n&quot;, detect_type(0x10, true));
  printf(&quot;0xFF, true: '%-20s'\n&quot;, detect_type(0xFF, true));
  return 0;
}
</pre></div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e290" id="d0e290"></a>From Nevin Liber
<tt class="email">&lt;<a href=
"mailto:nevin@eviloverlord.com">nevin@eviloverlord.com</a>&gt;</tt></h3>
</div>
<p>First observation: I'm not sure what compiler the student was
using. I couldn't get it to compile under either CodeWarrior 9.5 or
gcc 2.96, even turning off all the warnings I could.</p>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e297" id="d0e297"></a>Bug #1: The
compiler error message (this one from Metrowerks; gcc is similar)
points out the bug:</h4>
</div>
<pre class="screen">
Error : illegal implicit conversion from
'char *' to 'unsigned char'
Detect_type.c line 34     {0x00, &quot;Sobre V PK Test&quot;},
</pre>
<p>Tracing back, <span class="structname">struct decidetest</span>
has three elements while each of the initializers for the
<tt class="varname">cadenatest</tt> array only have two elements.
Removing element <i class="structfield"><tt>numero</tt></i> from
<span class="structname">decidetest</span> fixes the bug. Writing a
little test harness:</p>
<pre class="programlisting">
#include &quot;Detect_type.h&quot; /* Detect_type(...) 
                            prototype */
#include &lt;stdio.h&gt;

int main()
{
  unsigned int valor;
  for (valor = 0xa000 - 1;
       valor &lt;= 0xa000 + 1; ++valor)
  {
    static const unsigned char tipus[] =
      { 0x00, 0x02, 0x0e, 0x10, 0xff, 0xbe };
    unsigned t;
    for (t = 0;
         t != sizeof(tipus)/sizeof(tipus[0]);
         ++t)
    {
      printf(&quot;Detect_type(0x%.2x, 0x%.4x)&quot;
        &quot; ==\&quot;%s\&quot;\n&quot;, tipus[t], valor,
Detect_type(tipus[t], valor));
}
}
return 0;
}
</pre>
<p>I get the following output:</p>
<pre class="screen">
Detect_type(0x00, 0x9fff) == &quot;Sobre V PK &quot;
Detect_type(0x02, 0x9fff) == &quot;Sobre V RMS &quot;
Detect_type(0x0e, 0x9fff) == &quot;-Power OFF-&quot;
Detect_type(0x10, 0x9fff) == &quot;-Power ON-&quot;
Detect_type(0xff, 0x9fff) == &quot; &quot;
Detect_type(0xbe, 0x9fff) == &quot;&amp;nbsp; &quot;
Detect_type(0x00, 0xa000) == &quot;Sobre V PK Test&quot; 
Detect_type(0x02, 0xa000) == &quot;Sobre V RMS Test&quot; 
Detect_type(0x0e, 0xa000) == &quot;-Power OFF-&quot; Detect_type(0x10, 0xa000) == &quot;-Power ON-&quot;
Detect_type(0xff, 0xa000) == &quot; &quot;
Detect_type(0xbe, 0xa000) == &quot;&amp;nbsp; &quot;
Detect_type(0x00, 0xa001) == &quot;Sobre V PK Test&quot; 
Detect_type(0x02, 0xa001) == &quot;Sobre V RMS Test&quot; 
Detect_type(0x0e, 0xa001) == &quot;-Power OFF-&quot; Detect_type(0x10, 0xa001) == &quot;-Power ON-&quot;
Detect_type(0xff, 0xa001) == &quot; &quot;
Detect_type(0xbe, 0xa001) == &quot;&amp;nbsp; &quot;
</pre>
<p>Now, the student said if <tt class="varname">valor</tt> is not
above 0xa0000, then '<span class="structname">decide</span>' is
used. While my intuition makes me suspect he wasn't being precise,
since I can't ask him in person, I have to go with what he
said.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e331" id="d0e331"></a>Bug #2: The edge
case of 0xa000 is incorrect.</h4>
</div>
<p>Fixing those two bugs:</p>
<pre class="programlisting">
char* Detect_type(unsigned char tipus,
       unsigned int valor)
{
int i;
static char escape[16] = &quot;&amp;nbsp;          &quot;;
static struct decide {
unsigned num;
char *string;
} cadena [] = {
          {0x00, &quot;Sobre V PK &quot;},
          {0x02, &quot;Sobre V RMS &quot;},
          {0x0E, &quot;-Power OFF-&quot;},
          {0x10, &quot;-Power ON-&quot;},
          {0xff, &quot; &quot;},
};

static struct decidetest {
/* Bug #1: unsigned numero; */
unsigned char num;
char *string;
} cadenatest [] = {
          {0x00, &quot;Sobre V PK Test&quot;},
          {0x02, &quot;Sobre V RMS Test&quot;},
          {0x0E, &quot;-Power OFF-&quot;},
          {0x10, &quot;-Power ON-&quot;},
          {0xff, &quot; &quot;},
};

if (0xA000 &lt; valor) /* Bug #2: if (valor &gt;= 0xA000) */
   {
     for(i = 0; i &lt; sizeof(cadenatest) /
         sizeof(cadenatest[0]); i++)
         if(cadenatest[i].num == tipus)
           return cadenatest[i].string;
   }
else
   {
     for(i = 0; i &lt; sizeof(cadena) /
         sizeof(cadena[0]); i++)
     if(cadena[i].num == tipus)
         return cadena[i].string;
   }

return (escape);
}
</pre>
<p>While this is now producing correct output, it can be made a lot
better.</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>Formatting. At a minimum, function bodies are indented and
<tt class="literal">struct</tt> members are indented inside their
<tt class="literal">struct</tt>s. This just makes it easier to see
the underlying structure of the code.</p>
</li>
<li>
<p>Types. The type of <tt class="varname">tipus</tt>, <i class=
"structfield"><tt>decide.num</tt></i> and <i class=
"structfield"><tt>decidetest.num</tt></i> should all match. I would
add the following:</p>
<pre class="programlisting">
typedef unsigned char tipus_t;
</pre>
<p>and change the types for all three of those variables to
<tt class="type">tipus_t</tt>.</p>
</li>
<li>
<p>String literals. <tt class="varname">escape</tt> is declared to
have a size of 16 bytes, yet the literal that initializes it has a
size of only 15 bytes (including the trailing '\0'). Plus, most of
the other string literals have a size of 17 bytes. A reasonable
guess is that the caller is expecting any string returned to have a
size of 17 bytes. Additionally, there is no reason to store escape
in a function static variable, since we can return the literal
directly. Finally, since we are returning string literals, the
caller shouldn't modify the elements in those string literals;
therefore, the function should return a <tt class="type">const
char*</tt>.</p>
</li>
</ol>
</div>
<p>And while we are on the subject of <tt class=
"literal">const</tt>, both <tt class="varname">cadena</tt> and
<tt class="varname">cadenatest</tt> should be <tt class=
"literal">static const struct</tt>s, to insure future maintainers
of the code don't modify them.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e392" id="d0e392"></a>Issue #3:
Refactoring the structs</h4>
</div>
<p>Looking at <span class="structname">decide</span> and
<span class="structname">decidetest</span> now, I noticed that they
have exactly the same members. So I made them instances of the same
<tt class="literal">struct</tt>, which I call <span class=
"structname">decide_t</span>.</p>
</div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e409" id="d0e409"></a>Issue #4:
Declarations should be closer to use</h4>
</div>
<p>The <tt class="varname">cadenatest</tt> array is only needed
when <tt class="literal">valor &gt; 0xA000</tt>, and the <tt class=
"varname">cadena</tt> array is only needed when <tt class=
"literal">valor &lt;= 0xA000</tt>, so I moved their declarations
into their respective <tt class="literal">if</tt> clauses.</p>
<p>Putting all of that stuff together, the code now looks like:</p>
<pre class="programlisting">
typedef unsigned char tipus_t;

const char* Detect_type(tipus_t tipus, unsigned int valor)
{
  /* static char escape[16] = &quot;&amp;nbsp; &quot;; */
  struct decide_t {
    tipus_t num;
    const char* string;
};
if (0xA000 &lt; valor) {
  static const struct decide_t
    cadenatest[] = {
        {0x00, &quot;Sobre V PK Test&quot;},
        {0x02, &quot;Sobre V RMS Test&quot;},
        {0x0E, &quot;-Power OFF- &quot;},
        {0x10, &quot;-Power ON- &quot;},
        {0xff, &quot; &quot;},
  };
  int i;
  for (i = 0; sizeof(cadenatest) / sizeof(cadenatest[0]) &gt; i; ++i)
    if (cadenatest[i].num == tipus) {
      return cadenatest[i].string;
    }
  } else {
    static const struct decide_t cadena[] = {
        {0x00, &quot;Sobre V PK &quot;},
        {0x02, &quot;Sobre V RMS &quot;},
        {0x0E, &quot;-Power OFF- &quot;},
        {0x10, &quot;-Power ON- &quot;},
        {0xff, &quot; &quot;},
    };
    int i;
    for (i = 0; sizeof(cadena) / sizeof(cadena[0]) &gt; i; ++i)
    if (cadena[i].num == tipus) {
      return cadena[i].string;
    }
  }
  return &quot;&amp;nbsp; &quot;;
}
</pre></div>
<div class="sect3" lang="en">
<div class="titlepage">
<h3><a name="d0e433" id="d0e433"></a>Issue #5:
Eliminate the loops</h4>
</div>
<p>Hand coded loops are both error-prone and algorithmically slow
(O(n)). We can do better by using a switch statement. While some
folks might squawk at having multiple returns, I found it easier as
I didn't need any local or static variables (other than the
return). Here is the complete redesign:</p>
<pre class="programlisting">
const char* Detect_type(unsigned char tipus, unsigned int valor) {
  if (0xA000 &lt; valor) {
    switch (tipus) {
    case 0x00:
      return &quot;Sobre V PK Test&quot;;
    case 0x02:
      return &quot;Sobre V RMS Test&quot;;
    case 0x0e:
      return &quot;-Power OFF- &quot;;
    case 0x10:
      return &quot;-Power ON- &quot;;
    case 0xff:
      return &quot; &quot;;
  };
} else {
  switch (tipus) {
  case 0x00:
    return &quot;Sobre V PK &quot;;
    case 0x02:
      return &quot;Sobre V RMS &quot;;
    case 0x0e:
      return &quot;-Power OFF- &quot;;
    case 0x10:
      return &quot;-Power ON- &quot;;
    case 0xff:
      return &quot; &quot;;
    };
     }
  return &quot;&amp;nbsp; &quot;;
}
</pre></div>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e440" id="d0e440"></a>Commentary</h3>
</div>
<p>The student claimed <span class="emphasis"><em>the function
compiles all right</em></span> - but they were unlucky with their
compiler! As both entrants found with gcc, many compilers will not
actually compile the code - and some will only compile it as 'C'
code but not as 'C++' code. Actually, I suspect that some warnings
were generated for the student but they probably ignored them.
Compiler warnings for computer programmers are much like pain is
for athletes - something is wrong and simply pressing on may cause
more serious damage.</p>
<p>The basic problem was initialising a structure (<span class=
"structname">decidetest</span>) with the wrong number of data
values. However the code hid this problem since the two data
structures were accessed in such a similar fashion that the reader
expected they were defined identically. I would suggest the writer
of the code should follow the so-called 'principle of least
surprise' and use the same structure for both arrays.</p>
<p>As Roger's solution shows making the two structures share a
common structure also makes it easier to avoid code duplication -
the same loop can be used for both the data structures (although in
this case it also changed the loop termination condition from a
count to a test of a 'special value' - NULL).</p>
<p>An approach that could be considered as an alternative to a
<tt class="literal">switch</tt> statement is a 'library' solution -
since the arrays are sequential the standard 'C' library function
<tt class="function">bsearch</tt> can be used to find the match.
This would avoid writing an explicit loop at all but retains the
explicit data structure.</p>
</div>
<div class="sect2" lang="en">
<div class="titlepage">
<h3><a name="d0e463" id="d0e463"></a>The Winner of
SCC 34</h3>
</div>
<p>The editor's choice is: Roger Leigh</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">
<div>
<h2><a name="d0e473" id="d0e473"></a>Student Code
Critique 35</h2>
</div>
<div>
<h3>(Submissions to <tt class="email">&lt;<a href=
"mailto:scc@accu.org">scc@accu.org</a>&gt;</tt> by September
1st)</h3>
</div>
</div>
<p>Here is a C++ header file with a number of potential problems.
Please critique the code to help the student identify the problems
and to help them to provide some better solutions.</p>
<p>Note: the class <tt class="classname">Report</tt> is not shown.
It contains a large amount of data, which can be explicitly deleted
by a call to <tt class="function">ClearAll</tt>.</p>
<pre class="programlisting">
// Reports : vector of reports
class Reports : public map&lt;Data*, Report&gt;
{
public:
  Reports() : nIndex(0) {}
  void ClearAll()
  {
    for (iterator iter=begin();
         iter != end(); iter++)
      (*iter).second.ClearAll();
  }

  Report&amp; GetReport(int nReport)
  {
    int nSize = size();
    assert(nReport &lt; nSize);
    if (nIndex == 0 || nIndex &gt; nReport || 
                    nIndex &gt;=(nSize-1))
  {
    iter = begin();
    nIndex = 0;
  }
  for (; iter != end(); iter++, nIndex++)
  {
    if (nIndex == nReport)
      return iter-&gt;second;
  }
  // keep compiler happy
  return *((Report*)0);
}

protected:
  int nIndex;
  iterator iter;
}; 
</pre></div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
