    <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  :: Applying OO to C</title>
        <link>https://members.accu.org/index.php/articles/1156</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 + CVu Journal Vol 14, #2 - Apr 2002</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/c77/">CVu</a>

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

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

                    -                        <a href="https://members.accu.org/index.php/articles/c65+115/">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;Applying OO to C</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 April 2002 13:15:50 +01:00 or Wed, 03 April 2002 13:15:50 +01:00</p>
<p><strong>Summary:</strong>&nbsp;<p>It is possible to apply OO techniques to make better C programs and that is the thrust of this article.</p></p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id="d0e18"></a>1. Why C and
OO.</h2>
</div>
<p>C of itself lacks support for object-orientated programming
(OOP). There are no classes, overloading, inheritance or other nice
OOP features that make C++ and Java OO languages and as we all know
OO is a good thing. Unfortunately there are a large number of
applications still to be written in C because there is no
alternative. Real-time developments soldier on using C and
assembler, and some products will not be developed in C++ or Java
because of safety considerations.</p>
<p>But it is possible to apply OO techniques to make better C
programs and that is the thrust of this article.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e25" id="d0e25"></a>2. The opaque
type</h2>
</div>
<p>The first building block is the opaque type. An application
programmer is presented with a set of services that manipulate
objects of type <tt class="type">T</tt> but because of how
<tt class="type">T</tt> is defined she unaware of the construction
of the type. Basically the programmer is not given any information
about <tt class="type">T</tt> so cannot rely on <tt class=
"type">T</tt>'s construction, i.e., fiddle with it.</p>
<p>The standard C library has the <tt class="type">FILE</tt> type
which is almost opaque-all the services only use pointers to a
<tt class="type">FILE</tt> object-but the construction of
<tt class="type">FILE</tt> is visible, you can find out what it is
made of and that means you can write code that assumes something
about it.</p>
<p>A true opaque type reveals nothing and this is how it is done; I
use typedefs to make the code more understandable.</p>
<p>In a header file declare the type and services that use pointers
to type:</p>
<pre class="programlisting">
typedef struct Ttag T; 
/* T is the opaque type */
extern T* get_a_T(void); 
/* create on free store/retrieve a new T */
extern void finish_with_a_T(T*); 
/* delete from free store/put back a T */
//... other services
</pre>
<p>In the source file defining the services, the definition of
<tt class="type">T</tt> is completed and the services defined:</p>
<pre class="programlisting">
struct Ttag {
//.. elements as required, e.g. int thingy;
};
T* get_a_T(void) {return malloc(sizeof T);
void finish_with_a_T(T* t) {if(t) free(t);}
//... other services
</pre>
<p>The user of these services cannot determine the data structure
of a <tt class="type">T</tt>! This is because the definition is
completed inside the C source file. With this approach we can
encapsulate services and operations because we have hidden all data
details from the user. Best bit - we can change the implementation
and the user will be unaware. Stage 1 of OO C achieved.</p>
<p>In the code above I ignored the problem of safe cleanup of
objects, partly because in C the only mechanisms available are:</p>
<div class="orderedlist">
<ol type="1">
<li>
<p>use a garbage collection library to replace the <tt class=
"function">malloc</tt>/<tt class="function">free</tt> calls;</p>
</li>
<li>
<p>use <tt class="function">atexit()</tt> to register a clean up
function for objects created by <tt class=
"function">get_a_T()</tt>. The function will get called when the
program exits because of a completion of <tt class=
"function">main()</tt> or calls to <tt class=
"function">exit()</tt>. The price is nothing gets cleared up until
exit. Installing the function could be carried out within the call
to <tt class="function">get_a_T()</tt> - see lazy evaluation
example below;</p>
</li>
<li>
<p>require the user match creation with destruction, i.e., for
every <tt class="type">T</tt> created (?) with <tt class=
"function">get_a_T()</tt> there must be a corresponding call to
<tt class="function">finish_with_a_T()</tt> for that object. The
user may have to guarantee the destruction under all circumstances
by using the <tt class="function">atexit()</tt> mechanism.</p>
</li>
</ol>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e116" id="d0e116"></a>3. An example
of opaque types in practice - Iteration</h2>
</div>
<p>The classic iteration in C is to use a <tt class=
"literal">for</tt> loop:</p>
<pre class="programlisting">
for(i = 0; i &lt; N; i++) {}
</pre>
<p>C++ iteration could use a <tt class="literal">for</tt> loop, but
the Standard Template Library <tt class="function">for_each</tt>
function can be employed too - it scans a range calling the user
defined handler:</p>
<pre class="programlisting">
for_each (x.begin(), x.end(), doSomething);
//where x is some sort of container
</pre>
<p>Java has its own idioms (Java 1.1 has the <tt class=
"classname">Enumeration</tt> class and 1.2 adds the <tt class=
"classname">Iterator</tt> class):</p>
<pre class="programlisting">
Enumeration e = x.enumerate();
while(e.hasMoreElements()){
  MyClass mc = (MyClass) e.nextElement();
  mc.doSomething();
}
</pre>
<p>Imagine we want a simple directory lister that can be used on a
number of platforms. How directory information is acquired is
intimately related to the operating system, so as good OO
practitioners, we want to hide the details from the user and
contain the variances by linking in platform dependent source
files. We define a universal enumeration interface header file,
<tt class="filename">Enumerate.h</tt>, and one of many
enumerations, for example <tt class="filename">FileEnum.h</tt>:</p>
<pre class="programlisting">
// Enumerate.h
#ifndef ENUMERATE_H_
#define ENUMERATE_H_
typedef struct EnumerationTag Enumeration;
#endif 
// FileEnum.h
// a simple minded example, lists files on the 
// drive at its current directory 
#ifndef FILEENUM_H_
#define FILEENUM_H_
#include &quot;enumerate.h&quot;
extern Enumeration * 
      FileEnum_get_enumeration(char drive);
extern int 
    FileEnum_hasMoreElements(Enumeration *);
extern char const *
       FileEnum_nextElement(Enumeration *);
extern void FileEnum_delete(Enumeration *);
#endif
</pre>
<p>The source for <tt class="classname">FileEnum</tt>, based on
Borland's <tt class="filename">dir.h</tt> (DOS). Of course none of
this is visible to the user of <tt class="classname">FileEnum</tt>
services:</p>
<pre class="programlisting">
// FileEnum.c
#include &quot;FileEnum.h&quot;
#include &lt;dir.h&gt;
#include &lt;string.h&gt;
#define NAME_LEN 256     
// for 32 dos bit name is 256 bytes
struct EnumerationTag {   
// completion of the opaque type
  struct ffblk ffblk;
  int exists;
  char name[NAME_LEN]; 
};
Enumeration * 
    FileEnum_get_enumeration(char drive) {
  Enumeration * e = malloc(sizeof(Enumeration));
  if(e != NULL) {
    char buf[6] = &quot; :*.*&quot;;
    buf[0] = drive;
/* should check if the drive exists, simple example though */
    if(findfirst(buf, &amp;e-&gt;ffblk, 0
              /*normal files*/) == 0)
      e-&gt;exists = 1;
    else e-&gt;exists = 0;
  }
  return e; 
}
int FileEnum_hasMoreElements(Enumeration * e){
  if(e != NULL) return e-&gt;exists;
  return 0;
}
char const * FileEnum_nextElement(
                    Enumeration * e) {
  if(e != NULL) {
// copy filename before overwriting ffblk 
    strcpy(e-&gt;name, e-&gt;ffblk.ff_name);
    if(findnext(&amp;e-&gt;ffblk) == 0)
      e-&gt;exists = 1;
    else e-&gt;exists = 0;
    return(char const *) e-&gt;name;
  }
  return &quot;&quot;;
}
void FileEnum_delete(Enumeration * e) {
  if(e != NULL)
    free(e);
}
</pre>
<p>Finally user code looks like this:</p>
<pre class="programlisting">
//printDir.c
#include &quot;FileEnum.h&quot;
#include &lt;stdio.h&gt;
static void printDirectory(char drive) {
  Enumeration * e = 
          FileEnum_get_enumeration(drive);
  while(FileEnum_hasMoreElements(e))
    printf(&quot;%s\n&quot;, FileEnum_nextElement(e));
  FileEnum_delete(e);
}
</pre>
<p>The implementation of <tt class="classname">FileEnum</tt> can
completely change without user code changing, and without having to
re-compile the user code. The user code cannot break if the members
of <tt class="classname">Enumeration</tt> change. The local
variable <tt class="varname">e</tt> in <tt class=
"function">printDirectory</tt> can be re-used for another type of
iteration because it has no definition within the user's
domain.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e187" id="d0e187"></a>4.
Polymorphism</h2>
</div>
<p>It's a shame we have to use specific calls when the <tt class=
"classname">Enumeration</tt> type is anonymous. This can be solved
at a price and that price is a partial definition of <tt class=
"classname">Enumeration</tt> in &quot;<tt class=
"filename">enumerate.h</tt>&quot;, something like:</p>
<pre class="programlisting">
/* Enumerate.h */
typedef struct EnumerateTagInternals EnumerateInternals; // opaque type
/* function types */
typedef int 
  (hasMoreElements_fn)(EnumerateInternals *); 
typedef void * 
    (nextElement_fn)(EnumerateInternals *); 
typedef void (enumerationDeleter_fn)(void); 
typedef struct {
  hasMoreElements_fn     * hasMoreElements;
  nextElement_fn         * nextElement;
  enumerationDeleter_fn  * deleter;
  EnumerateInternals     * internals;
} Enumeration;
/* generic functions */
extern int hasMoreElements(Enumeration *);
extern void * nextElement(Enumeration *);
extern void enumerationDeleter(Enumeration *);
</pre>
<p>We need an <tt class="filename">Enumerate.c</tt>:</p>
<pre class="programlisting">
int hasMoreElements(Enumeration * e)
  {return(e-&gt;hasMoreElements)(e-&gt;internals); }
void * nextElement(Enumeration * e){
  { return(e-&gt;nextElement)(e-&gt;internals); } void enumerationDeleter(Enumeration * e)
  {(e-&gt;deleter)(); }
</pre>
<p><tt class="classname">FileEnum</tt>'s header and source would
be:</p>
<pre class="programlisting">
/* FileEnum.h */
#ifndef FILEENUM_H_
#define FILEENUM_H_
#include &quot;enumerate.h&quot;
extern Enumeration * 
      FileEnum_get_enumeration(char drive);
extern void FileEnum_delete(Enumeration *);
#endif
/* FileEnum.c */
#include &quot;fileenum.h&quot;
#include &lt;dir.h&gt;
#include &lt;string.h&gt;
#include &lt;stdlib.h&gt;
#define NAME_LEN 256
struct EnumerateInternals_tag { 
// completion of opaque type
  struct ffblk ffblk;
  int exists;
  char name[NAME_LEN];
};
static int FileEnum_hasMoreElements(EnumerateInternals* i){
  if(i != NULL) return i-&gt;exists;
  return 0;
}
static void * 
FileEnum_nextElement(EnumerateInternals * i){
  if(i != NULL){
    strcpy(i-&gt;name, i-&gt;ffblk.ff_name);
    if(findnext(&amp;i-&gt;ffblk) == 0)i-&gt;exists = 1;
    else i-&gt;exists = 0;
    return i-&gt;name;
  }
  return &quot;&quot;;
}
void FileEnum_delete(Enumeration * e){
  if(e != NULL)   {
    if(e-&gt;internals != NULL)
      free(e-&gt;internals);
    free(e);
  }
}
Enumeration * 
      FileEnum_get_enumeration(char drive){
  Enumeration * e=malloc(sizeof(Enumeration));
  if(e != NULL){
    e-&gt;internals =
        malloc(sizeof(EnumerateInternals));
    e-&gt;hasMoreElements =
        FileEnum_hasMoreElements;
    e-&gt;deleter = FileEnum_delete;
    e-&gt;nextElement = FileEnum_nextElement;
    if(e-&gt;internals != NULL) {
      char buf[] = &quot; :*.*&quot;;
      buf[0] = drive;
      if(!findfirst(buf, 
              &amp;e-&gt;internals-&gt;ffblk, 0)
        e-&gt;internals-&gt;exists = 1;
      else  e-&gt;internals-&gt;exists = 0;
    }
  }
  return e;
}
</pre>
<p>mplementers of Enumeration services use the above as a template,
but users are then more-or-less forced to use a consistent approach
when they use these services - see user code below. This makes for
consistency in large projects and that's a good thing for
maintenance.</p>
<pre class="programlisting">
/* printDir.c */
#include &quot;Enumerate.h&quot;
#include &quot;FileEnum.h&quot;
#include &lt;stdio.h&gt;
static void printDirectory(char drive){
  Enumeration * e = 
        FileEnum_get_enumeration(drive);
  while (hasMoreElements(e)){
    printf(&quot;%s\n&quot;, (char*)nextElement(e));
  }
  enumerationDeleter(e);
}
</pre>
<p>Note that only the creation of the <tt class=
"classname">Enumeration</tt> object is specific, the rest of the
code is generic.</p>
<p>Why is this polymorphic? Imagine we had defined a number of
different <tt class="classname">Enumeration</tt> types and created
some objects of these types. Now if they were held in a table we
could scan the table and process all of them the same way- they
meet the Liskov substitution principle because the interface is the
same and (if the implementers have got it right) they behave the
same.</p>
<p>Caveat. Not quite guaranteed because the return type of
<tt class="function">nextElement_fn</tt> is <tt class="type">void
*</tt> so it is possible to return a different type to the one you
are expecting - however I leave that problem as an exercise for you
to solve (hint: time for another opaque type).</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e238" id="d0e238"></a>5. Lazy
evaluation</h2>
</div>
<p>This is here to show a classic pattern in C, often found in C++
and Java, and to fill in the details for a reference I made
earlier.</p>
<p>This technique is used quite often to hide initialisation from
the calling software. For example, supposing we wish to register a
cleanup function to be called on exit. The function should be
registered once only. On exit the function must then cleanup
everything in its jurisdiction. Ignoring the issue of how it knows
what to clean, let's see this in action:</p>
<pre class="programlisting">
#include &lt;stdlib.h&gt; // atexit
static int cleanme = 0; // flag
static void cleanup(void) {
/* tidy up loose ends: files open, deal wih malloc'ed and not freed in this module etc. */
}
void someFunctionCalledByTheUserThatMallocs(void){
    if(cleanme ==0) {
      cleanme = 1; atexit(cleanup); }
// rest of function including optional malloc
}
</pre>
<p>Although this does not look interesting, it allows the user to
implement safe memory and resource handling schemes, and can be
used to get rid of <tt class="function">delete</tt> functions at
the cost of, say, allocated memory not freed until program
closure.</p>
<p>Lazy evaluation can be used anywhere resources have to be set up
in advance of access. I have used it successfully to set up reading
parameters from battery backed ram where there was no control over
the user calls - they could happen anytime including during system
initialisation.</p>
<p>The OO bit is the user has no idea that something special is
happening apart from the first call taking somewhat longer.</p>
<p>An extension to lazy evaluation is the concept of the singleton
whereby a single instance of data is created on demand and no
further instances are allowed:</p>
<pre class="programlisting">
static T * singleton = NULL;
static void cleanupSingleton(void); 
// tidies up and frees the singleton at exit
T * getSharedT(void){
  if(singleton == NULL){
    atexit(cleanupSingleton); 
    singleton = malloc(sizeof(T));
// set up the singleton..
  }
  return singleton;
}
</pre>
<p>Note how creation and cleanup of the singleton T object are
contained within the call to <tt class=
"function">getSharedT</tt>.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e265" id="d0e265"></a>6.
Wash-up</h2>
</div>
<p>There is more to say on the subject of OO C. Unfortunately I
have run out of time to do so. I would have liked to try to cover
the problem of separating out the what from the how, e.g. a queue
object that can hold any type of object in a type safe manner -
much easier in C++ and Java than C.</p>
<p>If you have found this article useful or have any comments
please let me know. Enough encouragement and I might write some
more.</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
