    <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  :: A Code Review</title>
        <link>https://members.accu.org/index.php/articles/763</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">Student Code Critiques from CVu journal. + CVu Journal Vol 11, #2 - Feb 1999</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/c184/">Journal Columns</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c183/">Code Critique</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/c77/">CVu</a>

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

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

                    -                        <a href="https://members.accu.org/index.php/articles/c183+133/">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;A Code Review</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 February 1999 13:15:29 +00:00 or Wed, 03 February 1999 13:15:29 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="section" lang="en">
<div class="titlepage">
<h2><a name="d0e16" id="d0e16"></a></h2>
</div>
<p>I fished the following from one of the Internet newsgroups. The
writer provided a very substantial chunk of source with the
following pre-amble:</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>I sure could use some help. This program is an in progress
program for my C programming class. It was working pretty well;
however, we just started learning about structures and binary
files. This lab (11) I was supposed to store data in a binary file
and create a new function <tt class="function">report()</tt> that
displays the contents of the file on screen. I am obviously having
problems with this. Any help or suggestions will be greatly
appreciated.</p>
</blockquote>
</div>
<pre class="programlisting">
/*********************************
*     PRODINV.H
Include file containing program constants, function 
prototypes, and structure declarations for CIS 32A 
class project.
**********************************/
</pre>
<p>It would have been a good idea to include a sentinel at the
beginning of this header file. In a small lab project you will get
away without one but good developing good habits from the start
will pay dividends later on. So your header file should start
with:</p>
<pre class="programlisting">
#ifndef PRODINV_H
#define PRODINV_H
</pre>
<p>and end with:</p>
<pre class="programlisting">
#endif
</pre>
<p>And his code continues:</p>
<pre class="programlisting">
#define ADD (1'     /* Menu options */
#define REPORT '2'
#define DELETE '3'
#define CHANGE '4'
#define QUIT '5'
</pre>
<p>I would strongly advocate that you not (a) use the pre-processor
for these and (b) use character codes for the values. I can see no
advantage in doing so, particularly as the normal input to a C
program is <tt class="type">int</tt> (which maybe internally
converted to a <tt class="type">char</tt>). I would replace the
above with:</p>
<pre class="programlisting">
enum MenuOptions { add_mo = 1,
                   report_mo,
                   delete_mo,
                   change_mo,
                   quit _mo};
</pre>
<p>I note that you later provide functions to do each of these
things. Unfortunately in C the global namespace is already
cluttered by standard library functions. I do not want to use
'delete' as an identifier because it is a C++ keyword. My next
choice 'remove' is a Standard C Library function name. In C++ I
would use a namespace to prevent possible clashes but I do not have
that option in C so I have resorted to using a suffix. I find
suffixes less invasive than prefixes and so make reading code
easier, what you want to know is at the front and the disambiguator
is at the back.</p>
<p>I would use an <tt class="literal">enum</tt> to provide your
product type and another for your inventory item limits.</p>
<pre class="programlisting">
/* Output headings / prompts      */
define HEADING &quot;California Sports Emporium&quot;
</pre>
<p>&lt;snipped other entries&gt;</p>
<pre class="programlisting">
define  PDESC_PROMPT &quot; description         : &quot;
</pre>
<p>You have applied a perfectly conventional solution to isolating
your various string literals but this is not efficient and is hard
to convert to using an input file to provide alternative headings
at execution time. There are various solutions to the problem. Here
are a couple for consideration:</p>
<p>Use pointers:</p>
<pre class="programlisting">
static char const * heading = &quot;California Sports Emporium&quot;;
</pre>
<p>The <tt class="literal">static</tt> qualification is to allow
use in multiple translation units without any risk of the linker
complaining. The <tt class="literal">const</tt> qualification is
because string literals are semantically immutable (and are
actually arrays of <tt class="type">char const</tt> in C++). Just
define the other strings in the same way. The problem is that this
doesn t easily convert to initialisation from a file. So I prefer
the following slightly more complicated mechanism:</p>
<pre class="programlisting">
char const * literal[ ] = { 
    &quot;California Sports Emporium&quot;,
/* rest of items */
    &quot;     description           :&quot;,
    &quot;Invalid string&quot; };
</pre>
<p>with the following <tt class="literal">enum</tt> to make use
comprehensible:</p>
<pre class="programlisting">
enum Literals {heading,
  /* other entries */
    pdesc_prompt,
    end_of_literals };
</pre>
<p>Now you can write: <tt class="literal">literal[heading]</tt>
etc. You will have to work a little harder to ensure that the array
of pointers is only initialised once. On the positive side, that
initialisation could be quickly converted to a run time one from a
file.</p>
<pre class="programlisting">
define  STRING_SIZE  80
define  MAX_STRING   30
</pre>
<p>I would prefer to replace those but the only portable (between C
and C++) is by using an <tt class="literal">enum</tt>. Pure C++
would use strings (which are expandable) and so would not need
these definitions.</p>
<pre class="programlisting">
              /* Function prototypes   */
void  vfnAdd(double *dpGTPrice,
             double *dpGTCost, FILE *fp);
int   ifnGetInt(char szPrompt[], int iLow,
                int iHigh); /* Gets a legal integer value */
int   ifnGetMore(void);
             /* determines user continue decision */
&lt; rest snipped &gt;
</pre>
<p>Look carefully at the above. What do you notice? The use of
Hungarian notation. Now ask yourself how useful it is? For example,
we know <tt class="function">vfnAdd</tt> is a function and if only
we knew what it did it would probably be obvious that it had a void
return. Look at those parameter names, how do they help? Yet the
writer hasn't provided a comment.</p>
<p>Hungarian notation has added nothing useful and the opportunity
to provide a properly descriptive identifier has been missed.</p>
<p>Look at the return type for that third function. Wouldn't some
form of boolean type have been better. And why no parameter? I
would have expected the prototype of that function to have been
something like:</p>
<pre class="programlisting">
Bool yesNo(char const * prompt);
           /* get y/n response to prompt */
</pre>
<p>(Assuming that <tt class="literal">enum Bool {false, true
};</tt> has been provided) I am not really happy with that function
name but I will live with it for now. I certainly do not find
variations on <tt class="function">getMore</tt> acceptable. That is
not what the function does, it gets a response to a question.</p>
<pre class="programlisting">
/* Structure definition        */
typedef struct STRUCT_INV { 
  int ipnum;
  int iptype;
  char szDesc[MAX_STRING];
  int iQty;
  double dCost;
  double dPrice;
  double dTotalProfit;
}sinventory;
</pre>
<p>Definitely not my style. If you are going to use <tt class=
"literal">typedef</tt> to provide a type name do not also provide a
<tt class="literal">struct</tt> tag, and certainly not one all in
uppercase. And look at those truly awful identifiers. Is <tt class=
"varname">ipnum</tt> a pointer to an <tt class="type">int</tt>? No.
But if you must name things this way, at least get the names
consistent. <tt class="varname">ipnum</tt> should be <tt class=
"varname">iPnum</tt>. Actually I suspect that it shouldn t even be
an <tt class="type">int</tt>, I guess that <tt class=
"varname">ipnum</tt> and <tt class="varname">iptype</tt> are
product codes that just happen to be written with digits and so
should be stored as some kind of string. Finally I would much
prefer the <tt class="literal">typedef</tt> typename was <tt class=
"type">InventoryEntry</tt> or, if you must, <tt class=
"type">sInventoryEntry</tt>.</p>
<pre class="programlisting">
sinventory  inventory;
</pre>
<p>And we finish with a definition of a global in a header file,
even in C++ this means that the header file can only be used once
per program.</p>
<p>And now to the main translation unit.</p>
<pre class="programlisting">
/****************************************
 This program gets inventory information for a 
sporting goods store from the user and saves it to 
disk. When all inventory items have been entered, 
the grand totals are displayed. A report function 
will print a report of items to screen for viewing.
****************************************/
#include &lt;stdio.h&gt;
#include &lt;conio.h&gt;
#include &lt;ctype.h&gt;
#include &lt;string.h&gt;
#include &quot;c:\c++\ansic\l11\prodinv.h&quot;
</pre>
<p>We haven t got passed the headers and we already have two points
to note. <tt class="filename">conio.h</tt> is a DOS specific header
file and would be much better placed after all the standard headers
with a relevant comment to help others who might not recognise it.
And then, why has the full path to <tt class=
"filename">prodinv.h</tt> been hard coded. And what about that
curious 'C++' in the path? I would want to ask the writer quite a
few questions just on the implications of that path.</p>
<pre class="programlisting">
void main() {
</pre>
<p>OK, so several compilers will fix up your code but <tt class=
"function">main</tt> returns an <tt class="type">int</tt>. It must
do because it is returns to <tt class="function">exit</tt> (that is
the way that C code works) and that function requires a value for
its status parameter.</p>
<pre class="programlisting">
  sinventory *sp;
  sp = &amp;inventory;
</pre>
<p>First we had a global variable and now we have a pointer to it.
Why? And even if you can justify that (which I doubt) why was it
not written as:</p>
<pre class="programlisting">
  sinventory * sp = &amp;inventory;
</pre>
<p>Why is the identifier sp? As we are using Hungarian notation
that should mean a nameless pointer to <tt class="type">short</tt>.
Also note that the use of the identifier inventory would imply that
this variable is some form of collection that represents the stock
and not just a single stock item.</p>
<pre class="programlisting">
  /* local varaibles  */
</pre>
<p>Not only is this comment valueless, it is also wrong, because
<tt class="varname">sp</tt> is also a local variable.</p>
<pre class="programlisting">
  char    cChoice;              /* user menu option */
  double  dGrandTotPrice = 0;   /* accumulator for price */
  double  dGrandTotCost = 0;    /*accumulator for cost */
  FILE    *fp;
</pre>
<p>More poor names. Why does the student adamantly refuse to give
his file pointers descriptive names?</p>
<pre class="programlisting">
  if((fp = fopen(&quot;PRODUCTS.DAT&quot;,&quot;w+b&quot;)) == NULL)  {
</pre>
<p>Why is this file being opened in binary mode? Actually this is
the cause of many of the problems that lead to the code being
posted. The student uses the file inconsistently.</p>
<pre class="programlisting">
    printf(&quot;Unable to open file for writing; Exiting\n&quot;);
    getch();
  }
</pre>
<p>So you said you were exiting, so why not do so? Something
like</p>
<pre class="programlisting">
exit(EXIT_FAILURE);
</pre>
<p>as a third statement in that compound statement block.</p>
<pre class="programlisting">
  else {
</pre>
<p>Of course this is not actually necessary if you call exit when
you find that you have failed to open the required file.</p>
<pre class="programlisting">
  while((cChoice = cfnMenu()) != QUIT)  {
      /* get user choice */
      switch(cChoice) {
      case  ADD:  vfnAdd(&amp;dGrandTotPrice,&amp;dGrandTotCost,fp);
        break;
      case  REPORT:  vfnReport(sp,fp);
        break;
      case  DELETE:  break;
      case  CHANGE: break;
      }
    }                                   /* display grand totals */
    vfnGrandTotal(dGrandTotCost,dGrandTotPrice);
    fclose(fp);
    printf(&quot;\n\nPress any key to exit.\n&quot;);
    getch();
  }
</pre>
<p>And here we could do with either a <tt class="literal">return
0;</tt> or <tt class="literal">exit(EXIT_SUCCESS);</tt></p>
<pre class="programlisting">
}
</pre>
<p>There are many hidden implications in this code (I have snipped
the function definitions because Francis is not going to allow me
space to inspect those as well). However the most important thing
is that this is not code that has been written from scratch. The
lab exercise is to modify already written code to use a file. So
why has so much poor coding got passed the course director? And the
following conclusion from the poster is even more disturbing. S/he
has almost finished this course. The posting concludes with:</p>
<div class="blockquote">
<blockquote class="blockquote">
<p>My next and last lab (project) is to add a <tt class=
"function">delete()</tt> and <tt class="function">change()</tt>
functions <tt class="function">delete()</tt> marks a product as
deleted by changing the product number to 0. I will have to modify
the <tt class="function">report()</tt> function to not display
these deleted records. The <tt class="function">change()</tt>
function will permit altering any field of a record except the
product number. Any suggestions on these will be appreciated
also.</p>
</blockquote>
</div>
<p>If only those teaching students to write C would do the job
properly the students would find programming easier and we would
have far less bad code being written. Note that the proposed use of
delete as a function name conflicts with a C++ keyword. The
resulting C code will not compile as C++. Sometimes this is
acceptable but I could hardly justify it here.</p>
<p>There is another question that should be crossing your mind. Why
is this young person learning C? C is a powerful language in its
problem domains but I would not include database processing among
them. I have a strong sense that this academic institution is
wasting its students' time. You would be deeply disturbed by a
medical school that taught blood letting as a standard medical
practice (even though there are times when such radical
old-fashioned techniques are useful.) The software industry needs
to get its act together and communicate its needs to the
universities and colleges.</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
