    <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  :: Tools and Un-smart Pointers</title>
        <link>https://members.accu.org/index.php/articles/895</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">CVu Journal Vol 11, #4 - Jun 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/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/c131/">114</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;Tools and Un-smart Pointers</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 June 1999 13:15:31 +01:00 or Thu, 03 June 1999 13:15:31 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="section" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id="d0e18"></a></h2>
</div>
<p>There are numerous tools that generate C code, ranging from
lex/flex and yacc/Bison (for generating lexical analysers and
parsers) to KL/1 (a parallel logic programming language developed
on the Japanese Fifth Generation project - <a href="???" target=
"_top">www.icot.or.jp/</a>). There are often limits to what you can
practically do when writing your own C/C++ code around these
tools.</p>
<p>KL/1, for example, was designed as a complete language in itself
rather than a tool, and as such it assumes that your program will
be written in KL/1 with only a tiny amount of inline C when you
really want it (like inline assembler in C). In some applications I
would prefer to use C or C++ with a minimal amount of KL/1 where
this is useful. The KL/1 paradigm is parallel components exchanging
data through streams (like Prolog lists, and the paradigm can be
useful even on a sequential processor), and it is quite conceivable
that you'd want to use this only for the top level of an algorithm
and not for every detail.</p>
<p>The problem is that KL/1, like many tools, only really allows
data to be exchanged with C in the form of integers (unless you
rely on undocumented implementation-specific features). It would be
nice to handle arbitrary objects as well, even if only the C code
can interpret them. (For brevity I use the term &quot;object&quot; to refer
to both classes and structs, whether or not they fit a pure OOP
definition of object, and I'm thinking of C programmers as well as
C++ ones.)</p>
<p>The natural way to achieve this is to create the objects on the
heap and store pointers to them in the integers, and many do this
in yacc by casting a pointer to an integer. However, this makes the
assumption that <tt class="literal">sizeof(int) &gt;=
sizeof(void*)</tt> (this assumption is especially dangerous if the
integers get converted to a different form by the tool, as in
KL/1), and it also becomes difficult to free objects that are no
longer needed. Especially if the tool can backtrack, you have to
know when it really has finished with something, but even then you
need to get hold of the pointer if you want to free an object.</p>
<p>In C Vu 8.3 I wrote about a multi-user text adventure I had
hacked out at a college for the blind. Every object was indirectly
referenced from an integer by a small group of functions that used
it as an offset into an array, and this was used for marshalling
data by the virtual memory (I was using DOS), the passing objects
around between machines, and of course the saving to disk. (Java
calls marshalling &quot;serializing&quot; but some don't like that because
it's the same as an unrelated OS term.) Francis suggested I read a
book about smart pointers, which were of course more elegant than
what I was doing because they were all wrapped up in classes that
could do interesting things. Incidentally I lost the code when I
left the college in an accident of the &quot;I think I've got this at
home already&quot; type.</p>
<p>For tools like KL/1 (I hope I don't offend anyone by treating it
as a tool), such &quot;un-smart&quot; indirection from array offsets could be
useful (and possibly encapsulated if desired). Integers do not have
to store actual memory addresses, and the addresses of all objects
are available for freeing (although you still have to make sure you
don't free things too soon). If appropriate, the marshalling for
various reasons is still possible, although it's not often you
would use it in an application like this.</p>
<p>Perhaps more useful for some tools is the ability to make
objects copy-on-write. Simply copy the pointer to a different
element in the master array and somehow mark both as copy-on-write,
then whenever you want to change the object, call something that
checks this and copies the object if necessary. KL/1 won't need
this often because variables are fixed once they're defined, but
general breadth-first tree searching might benefit. This can be
useful in some applications, e.g. a top-down parser that lists all
possible interpretations of a phrase in an ambiguous grammar.
Breadth-first algorithms (i.e. ones that check several branches of
possibilities at once) have the advantage that solutions are found
sooner if they are not far from the start (a recursive backtracking
algorithm may waste a lot of time exploring the wrong branch), as
well as possibilities of merging branches if they are common after
a while (very conceivable in ambiguous parsing) and cancelling
branches that for some reason can be decided to be futile by other
branches. Breadth-first algorithms don't need nearly so much stack
(because they don't need to backtrack), but they might need
numerous copies of the data structures that are nearly identical,
and here copy-on-write can be useful.</p>
<p>Aside: One way to implement a breadth-first search is using
BCPL-style co-routines - branch new ones when necessary. These are
like multithreading except that all context switching is under the
programmer's control, and although they were not carried over into
C (there is a C++ co-routine library somewhere) one can still think
in terms of them. It can get messy though. KL/1 is also interesting
because it runs by taking a clause from a heap of them, evaluating
it to give further clauses and throwing them back into the heap -
the only real control you have on the order of evaluation is that
it won't execute clauses whose &quot;guard&quot; conditions test variables
that aren't yet available. And you can of course use the classic
method of keeping a queue of nodes to look at (if it doesn't get
too big) and putting their sub-nodes on the end of the queue - to
do this you need to write your algorithm in such a way that it can
look at only one node each time it's called.</p>
<p>The main disadvantage of pointers via integers is that it throws
type checking to the wind, and imagine what would happen if you
accidentally tried to do pointer arithmetic. (The speed overhead in
the extra indirection is slight.) Run-time checks are a poor
substitute for compile-time checks. If you are dealing with objects
of more than one type, you would either have to be very careful or
use yet another tool to help you write the program.</p>
<p>Here is some C code that implements the most basic functionality
of the method, slightly obfuscated for space:</p>
<pre class="programlisting">
#include &lt;assert.h&gt;
#include &lt;stdlib.h&gt;
enum { initSize=50 };
void** master; int mSize;
int mPtr=1; /* not 0 so number 0 can mean null */
void zero(int x, int y) { for(;x&lt;y;x++) master[x]=NULL; }
void grow(int newSize) { 
    assert((master=(void**)realloc(master,sizeof(void*)*newSize))!=0);
     zero(mSize,newSize); mSize=newSize; 
}
void init() {
     assert((master=(void**)malloc(sizeof(void*)*(mSize=initSize)))!=0);
     zero(0,mSize); 
}
/* inline */ void readObj(int n) { return(assert(master[n]), master[n]); }
/* (readObj could be a macro but note that n would be evaluated twice) */
int newObj(void* p) { if(mPtr==mSize) grow(mSize&lt;&lt;1);  master[mPtr++]=p; return(mPtr-1); }
void freeObj(int n) { free(readObj(n));  master[n]=NULL; }
</pre>
<p>I have of course been assuming that only a single processor is
to be used (or at least the memory is shared); KL/1 supports
distributed memory parallelism and if this is used then provision
should be made or it. If you must do this, the safest method
(although slow) is probably to marshal objects and pass them
through KL/1's own mechanism; that adventure game's code would be
of little use here as although it was distributed it didn't exploit
concurrency - there was a token passing system for changing the
objects. In a real situation you would also want to re-use old
array elements and perhaps add more asserts to the code (the most
obvious being a bounds check).</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
