    <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 Usable C++ Dialect that is Safe Against Memory Corruption</title>
        <link>https://members.accu.org/index.php/journals/2407</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">Overload Journal #140 - August 2017 + Design of applications and programs</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/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c376/">o140</a>
                    (9)
<br />

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

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c67/">Design</a>
                    (236)
<br />

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

                    -                        <a href="https://members.accu.org/index.php/journals/c376+67/">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 Usable C++ Dialect that is Safe Against Memory Corruption</h1>
<p><strong>Author:</strong>&nbsp;Bob Schmidt</p>
<p>
<strong>Date:</strong> 07 August 2017 00:55:27 +01:00 or Mon, 07 August 2017 00:55:27 +01:00</p>
<p><strong>Summary:</strong>&nbsp;Suitable allocators for (Re)Actors can speed things up. Sergey Ignatchenko continues his investigation in Allocator for (Re)Actors (Part 2).</p>
<p><strong>Body:</strong>&nbsp;<p class="quote">We have this handy fusion reactor in the sky. You donâ€™t have to do anything, it just works.<em>~ Elon Musk</em></p>

<p class="EditorIntro">Disclaimer: as usual, the opinions within this article are those of â€˜No Bugsâ€™ Hare, and do not necessarily coincide with the opinions of the translators and <em>Overload</em> editors; also, please keep in mind that translation difficulties from Lapine (like those described in [<a href="[Loganberry04]">Loganberry04</a>]) might have prevented an exact translation. In addition, the translator and <em>Overload</em> expressly disclaim all responsibility from any action or inaction resulting from reading this article.</p>

<p>As we briefly discussed in Part I of this mini-series [<a href="#[NoBugs17]">NoBugs17</a>], message-passing technologies such as (Re)Actors (a.k.a. Actors, Reactors, ad hoc FSMs, and event-driven programs) have numerous advantages, ranging from being debuggable (including post-factum production debugging), to providing better overall performance.</p>

<p>In [<a href="#[NoBugs17]">NoBugs17</a>], we discussed an approach to handling allocations for (Re)Actors â€“ and were able to reach kinda-safety at least in what we named â€˜kinda-safeâ€™ and â€˜safe with relocationâ€™ mode. Unfortunately, kinda-safety didnâ€™t really provide the Holy Grailâ„¢ of safety against memory corruptions. Now, we can extend our allocation model with a few additional guidelines, and as long as weâ€™re following these rules/guidelines, our C++ programs WILL become perfectly safe against memory corruptions.</p>

<h2>#define (Re)Actors</h2>

<p>To make this article self-contained and make sure that weâ€™re all on the same page with terminology, letâ€™s repeat the definition of what weâ€™re considering: (Re)Actors [<a href="#[NoBugs17]">NoBugs17</a>].</p>

<p>Letâ€™s begin with a common denominator for all our (Re)Actors: a <code>GenericReactor</code>. <code>GenericReactor</code> is just an abstract class â€“ and has a pure virtual function <code>react()</code>:</p>

<pre class="programlisting">
  class GenericReactor {
    virtual void react(const Event&amp; ev) = 0;
  }</pre>

<p>Letâ€™s define what we will refer to as â€˜infrastructure codeâ€™: a piece of code which calls <code>GenericReactor</code>â€™s <code>react()</code>. Quite often this call will be within a so-called â€˜event loopâ€™ (Listing 1).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
std::unique_ptr&lt;GenericReactor&gt; r
  = reactorFactory.createReactor(...);
while(true) { //event loop
  Event ev = get_event();
    //from select(), libuv, ...
  r-&gt;react(ev);
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<p>Letâ€™s note that the <code>get_event()</code> function can obtain events from wherever we want; anything from <code>select()</code> (which is quite typical for servers) to libraries such as <em>libuv</em> (which is common for clients). </p>

<p>Also letâ€™s note that an event loop, such as the one above, is certainly <em>not</em> the only way to call <code>react()</code>: Iâ€™ve seen implementations of infrastructure code ranging from one running multiple (Re)Actors within the same thread, to another which deserialized (Re)Actor from DB, then called <code>react()</code> and then serialized (Re)Actor back to a database. Whatâ€™s important, though, is that even if <code>react()</code> can be called from different threads, it MUST be called <em>as if</em> it is one single thread (if necessary, all thread sync should be done OUTSIDE of our (Re)Actor, so <code>react()</code> doesnâ€™t need to bother about thread sync regardless of the infrastructure code in use). </p>

<p>Finally, letâ€™s refer to any specific derivative from <code>GenericReactor</code> (which implements our <code>react()</code> function) as a <code>SpecificReactor</code>:</p>

<pre class="programlisting">
  class SpecificReactor : public GenericReactor {
    void react(const Event&amp; ev) override;
  };</pre>

<p>In addition, letâ€™s observe that whenever (Re)Actor needs to communicate with another (Re)Actor â€“ adhering to the â€˜Do not communicate by sharing memory; instead, share memory by communicatingâ€™ principle â€“ it merely sends a message, and it is only this message which will be shared between (Re)Actors. In turn, this means that we can (and <em>should</em>) use single-threaded allocation for all (Re)Actor purposes â€“ except for allocation of those messages intended for inter-(Re)Actor communications. </p>

<h2>Rules to ensure memory safety</h2>

<p>With (Re)Actors defined, we can formulate our rules to make our (Re)Actor code (<code>Reactor::react()</code> and all the stuff called from it) perfectly safe.</p>

<p>First, letâ€™s postulate that there are three different types of pointers in our program: â€˜owningâ€™ pointers, â€˜softâ€™ pointers, and â€˜nakedâ€™ pointers.</p>

<p>â€˜Owningâ€™ pointers delete their contents in destructors, and within our rules, should comply with the following:</p>

<ul>
	<li>an â€˜owningâ€™ pointer is a template, semantically similar to <code>std::unique_ptr&lt;&gt;</code></li>

	<li>â€˜owningâ€™ pointers are obtained only from operator <code>new</code></li>

	<li>copying â€˜owningâ€™ pointers is not possible, but moving them is perfectly fine</li>

	<li>there is no explicit <code>delete</code>; however, there <em>is</em> a way to assign <code>nullptr</code> to the â€˜owningâ€™ pointer, effectively calling <code>destructor</code> and deleting the object. However, while the <code>destructor</code> will be called right away, implementation of our allocator will ensure that actual <em>freeing of the memory</em> will be <em>postponed</em> until the point when weâ€™re out of <code>Reactor::react()</code>. As weâ€™ll see below, it is important to ensure safety in cases when there is a â€˜nakedâ€™ pointer to the object being deleted.</li>
</ul>

<p>â€˜Softâ€™ pointers are obtained from â€˜owningâ€™ ones. Whenever weâ€™re trying to access an already deleted object via a â€˜softâ€™ pointer (or create a â€˜nakedâ€™ pointer from a â€˜softâ€™ pointer which points to an already deleted object) â€“ we are <em>guaranteed</em> to get an exception. â€˜Softâ€™ pointers should comply with the following:</p>

<ul>
	<li>a â€˜softâ€™ pointer is also a template, somewhat similar to <code>std::weak_ptr&lt;&gt;</code></li>

	<li>â€˜softâ€™ pointers are obtained from an â€˜owningâ€™ pointer, or as a copy of an existing â€˜softâ€™ pointer</li>

	<li>both copying and moving â€˜softâ€™ pointers is ok</li>

	<li>â€˜softâ€™ pointers can be implemented either using tombstones (with reference counting for the tombstones), or using the ID-comparison-based technique described in [<a href="#[NoBugs17]">NoBugs17</a>].</li>
</ul>

<p>â€˜Nakedâ€™ pointers are our usual C-style pointers â€“ and are inherently very dangerous as a result. Apparently, we can still handle them in a safe manner, as long as the following rules are followed:</p>

<ul>
	<li>our â€˜nakedâ€™ pointers are obtained <em>only</em> from â€˜owningâ€™ pointers, from â€˜softâ€™ pointers, or by taking an address of an existing on-stack object. This implies (a) that all pointer arithmetic is prohibited, and (b) that all casts which result in a pointer (except for <code>dynamic_cast&lt;&gt;</code>) are prohibited too.</li>

	<li>We <em>are</em> allowed to copy our â€˜nakedâ€™ pointers into another â€˜nakedâ€™ pointer of the same type; however, whenever weâ€™re copying a â€˜nakedâ€™ pointer, we MUST ensure that the lifetime of the copy is not longer than the lifetime of the original pointer.</li>
</ul>

<p>The most reliable way to enforce the â€˜lifetime is never extendedâ€™ rule above is to say that all copying of â€˜nakedâ€™ pointers is prohibited, except for a few well-defined cases:</p>

<ul>
	<li>Calling a function passing the pointer as a parameter, is ok.
		<p>NB: double-naked-pointers and references to naked pointers effectively allow to us to return the pointer back (see on returning â€˜nakedâ€™ pointer below) â€“ so assigning to such <code>*ptrs</code> should be prohibited.</p>
	</li>

		<li>Creating an on-stack copy of a â€˜nakedâ€™ pointer (initialized from another pointer: â€˜owningâ€™, â€˜softâ€™, or â€˜nakedâ€™) of is generally ok too.</li>
</ul>

<p>On the other hand, the following constructs are known to violate the â€˜lifetime is never extendedâ€™ rule, and are therefore prohibited:</p>

<ul>
	<li>Returning â€˜nakedâ€™ pointer(s). Instead, weâ€™ll need to return either the â€˜owningâ€™ or â€˜softâ€™ pointer(s). Actually, if we think about it, weâ€™ll see that is not that much of a restriction. If we want to return a pointer to an on-heap object, â€˜softâ€™ or â€˜owningâ€™ pointers are the way to go; and returning a pointer to our local stack is a Bad Ideaâ„¢ anyway. This only leaves us with functions such as <code>strchr()</code>, which tend to return a pointer on an object which was passed to them as a parameter â€“ but it is not difficult to find a different way to return this information (to implement an analogue of <code>strchr()</code> within our restrictions, we can always return an offset instead of the pointer).</li>

	<li>Assigning â€˜nakedâ€™ pointers to members of on-heap objects (and any naked-pointer parameter <em>may</em> happen to point to the heap) is prohibited. This can be seen as a stronger version of our restriction from [<a href="#[NoBugs17]">NoBugs17</a>], of â€˜(Re)Actor state cannot have â€˜nakedâ€™ pointersâ€™; as an important side-effect which weâ€™ll rely on later, this means that as soon as weâ€™re out of <code>Reactor::react()</code>, there are no â€˜nakedâ€™ pointers whatsoever.</li>
</ul>

<p>Note that the respective lists of ways to create pointers are exhaustive; in other words: the ONLY way to create an â€˜owningâ€™ pointer is from operator <code>new</code> of the same type; the ONLY ways to create a â€˜safeâ€™ pointer is (a) from an â€˜owningâ€™ pointer of the same base type, or (b) as a copy of a â€˜safeâ€™ pointer of the same type; and the ONLY way to create a â€˜nakedâ€™ pointer is from {â€˜owningâ€™|â€˜softâ€™|â€˜nakedâ€™} pointer as long as the â€˜nakedâ€™ pointer doesnâ€™t extend the lifetime of the original pointer.</p>

<p>This implies prohibiting casting <em>to</em> pointers (and also prohibits C-style <code>cast</code> and <code>static_cast&lt;&gt;</code> with respect to pointers; however, implicit pointer casts and <code>dynamic_cast&lt;&gt;</code> are ok). Note that although casting <em>from</em> pointers wonâ€™t cause memory corruption, it is not a good idea in general.</p>

<p>This also implies that assigning the result of <code>new</code> to anything except an â€˜owningâ€™ pointer is prohibited.</p>

<p>Implementations for both â€˜owningâ€™ and â€˜safeâ€™ pointers should take into account that their methods <em>may</em> be invoked after their destructor is called (see discussion in (*) paragraph below); in this case, weâ€™ll either guarantee that no pointer to a non-existing object will be returned, <em>or</em> (even better) will throw an exception.</p>

<p>Note that for the time being, we do NOT handle collections and arrays; in particular, we have to prohibit indexed dereferencing (<code>a[i]</code> is inherently dangerous unless weâ€™re ensuring boundary checks).</p>

<p>Thatâ€™s it â€“ weâ€™ve got our perfectly safe dialect of C++, and while it doesnâ€™t deal with arrays or collections, it is a very good foundation for further refinements.</p>

<h2>Proof sketch</h2>

<p>The formal proof of the program under the rules above is going to be lengthy and, well, formal, but a sketch of such a proof is as follows.</p>

<p>First, letâ€™s note that our rules do NOT allow the creation of any pointers, unless it is a pointer to an existing on-heap object, or an on-stack object (the latter is for â€˜nakedâ€™ pointers only). <em>NB: if we also want to deal with globals, this is trivial too, but for the time being letâ€™s prohibit globals within (Re)Actors, which is good practice anyway.</em></p>

<p>As a result, there is no risk of the pointer pointing somewhere where there was never an object, and the only risks weâ€™re facing are about the <em>pointers to objects which did exist but donâ€™t exist anymore</em>. We have two types of such objects: on-stack objects, and on-heap ones.</p>

<p>For on-stack objects which donâ€™t exist anymore:</p>

<ul>
	<li>To start with, only â€˜nakedâ€™ pointers can possibly point to on-stack objects</li>

	<li>Due to our â€˜the lifetime of a â€˜nakedâ€™ pointer never extendsâ€™ rule, weâ€™re guaranteed that a â€˜nakedâ€™ pointer will be destroyed <em>not later</em> than the object it points to, which means that we cannot possibly corrupt memory using it.</li>
</ul>

<p>For on-heap objects which donâ€™t exist anymore:</p>

<ul>
	<li>â€˜owningâ€™ pointers are inherently safe (according to our rules, there is no way to delete an object while an â€˜owningâ€™ pointer still points there)</li>

	<li>â€˜softâ€™ pointers are safe because of the runtime checks weâ€™re doing every time weâ€™re dereferencing them or converting them into a â€˜nakedâ€™ pointer (and throwing an exception if the object theyâ€™re pointing to doesnâ€™t exist anymore).</li>

	<li>â€˜nakedâ€™ pointers to on-heap objects are safe because of the same â€˜the lifetime never extendsâ€™ rule and because of the postponing the freeing of memory until weâ€™re outside <code>Reactor::react()</code>. Elaborating on it a bit: as we know that at the moment of conversion from an â€˜owningâ€™ pointer or a â€˜softâ€™ pointer to a â€˜nakedâ€™ pointer, the object did exist, and the memory wonâ€™t be actually freed until weâ€™re outside of <code>Reactor::react()</code>, this means that weâ€™re fine until weâ€™re outside of <code>Reactor::react()</code>; and as soon as weâ€™re outside of <code>Reactor::react()</code>, as discussed above, there are no â€˜nakedâ€™ pointers anymore, so there is no risk of them dereferencing the memory which weâ€™re going to free.</li>
</ul>

<p>(*) Note that via â€˜nakedâ€™ pointers, we <em>are</em> still able to access objects which have already had their destructors called (but memory unreleased); this means that to ensure safety, those objects from supporting libraries which donâ€™t follow the rules above themselves (in particular, collections) <em>must</em> ensure that their destructors leave the object in a â€˜safeâ€™ state (at least with no â€˜danglingâ€™ pointers left behind; more formally: there should be a firm guarantee that <em>any</em> operation over a destructed object cannot possibly cause memory corruption or return a pointer which is not a <code>nullptr</code>, though ideally it <em>should</em> cause an exception).</p>

<p>Phew. Unless Iâ€™m mistaken somewhere, it <em>seems</em> that we got our perfectly safe dialect of C++ (without collections, that is). </p>

<h2>Enter collections</h2>

<p class="quote">[Enter Romeo and Juliet]</p>
<p class="quote">Romeo: Speak your mind. You are as worried as the sum of yourself</p>
<p class="quote"> and the difference between my small smooth hamster and my nose. </p>
<p class="quote">Speak your mind!</p>
<p class="quote">Juliet: Speak YOUR mind! You are as bad as Hamlet! </p>
<p class="quote">You are as small as the difference between the square of the difference </p>
<p class="quote">between my little pony and your big hairy hound </p>
<p class="quote">and the cube of your sorry little codpiece. Speak your mind!</p>
<p class="quote">[Exit Romeo]</p>
<p class="quote">~ Program in The Shakespeare Programming Language</p>

<p>As noted above, collections (including arrays) are not covered by our original rules above. However, it is relatively easy to add them, by adding a few additional rules with regards to collections.</p>

<p>First, we will NOT use the usual iterators (including pointers within arrays); instead, weâ€™re using â€˜safe iteratorsâ€™. A â€˜safe iteratorâ€™ (or â€˜safe rangeâ€™) is a tuple/struct/class/â€¦ which contains:</p>

<ul>
	<li>An {'owning'|'soft'|'naked'} pointer/reference to the collection</li>

	<li>An iterator (or range) within the collection pointed out by the pointer above</li>
</ul>

<p>The second rule about collections is that <em>all</em> the access to the collections (including iterator dereferencing) MUST be written in a way which <em>guarantees</em> safety. </p>

<p>For example, if weâ€™re trying to access an element of the array via our â€˜safe iteratorâ€™, it is the job of the <code>operator*</code> of our â€˜safe iteratorâ€™ to ensure that it stays within the array (and to throw an exception otherwise).</p>

<p>This is certainly possible:</p>

<ul>
	<li>For arrays, we can always store the size of the array within our array collection, and check the validity of our â€˜safe iteratorâ€™ before dereferencing/indexing.</li>

	<li>Then, as all the <code>std::</code> collections are implemented either on top of single objects or on top of arrays, rewriting them in a safe manner is always possible based on the techniques which we already discussed.</li>

	<li>On the other hand, more optimal implementations <em>seem</em> to be possible for specific collections. As one example, <code>deque&lt;&gt;</code> can be implemented without following the rules discussed above <em>within its implementation</em>, and simply checking range of the iterator instead. In another example, tree-based collections can be optimized too.</li>
</ul>

<p>This way, whenever we want to use such a â€˜safe iteratorâ€™/â€˜safe rangeâ€™, first weâ€™ll reach the collection (relying on our usual safety guarantees for our {'owning'|'soft'|'naked'} pointers), and then the collection itself will guarantee that its own iterator is valid before dereferencing it.</p>

<h2>Different approaches to safety in infrastructure code and Reactor code</h2>

<p class="quote">20% of people consume 80% of beer<em>~ Pareto principle as applied to beer consumption</em></p>

<p>An observation (*) above, as well as the discussion about optimized collections, highlights one important property of our Perfectly Safe Reactors: </p>

<p class="blockquote"><em>we can (and often SHOULD) have different approaches to safety of the Reactor::react() and the rest of the code.</em></p>

<p>This dichotomy between infrastructure code and Reactor code is actually very important in practice. </p>

<p>Infrastructure code (including supporting libraries such as collections, etc.) is:</p>

<ul>
	<li>written once â€“ and then stays pretty much unchanged</li>

	<li>usually relatively small compared to the business-logic stuff</li>

	<li>called over and over</li>

	<li>often fits into the 5% of the code which takes 95% of the execution time</li>
</ul>

<p>In contrast, (Re)Actor code: </p>

<ul>
	<li>contains business logic, which has a tendency to be changed several times a day</li>

	<li>as with any business logic, its code base can be huuuuge</li>

	<li>most of this code is called only occasionally compared to the Infrastructure Code</li>

	<li>90% of it is glue code, which very rarely causes any performance issues</li>
</ul>

<p>As a result, we can observe that for small, never-changing, and performance-critical Infrastructure Code, it is both feasible and desirable to provide safe highly-optimized versions (which may or may not follow our rules above in the name of performance). On the other hand, for (Re)Actor Code, formal safety is usually much more important than bare performance. This is especially so as, in the case of our rules, the expected performance hit is pretty much negligible: the only two runtime checks weâ€™re doing happen at â€˜safeâ€™ pointer to â€˜nakedâ€™ pointer conversion (or at â€˜safeâ€™ pointer dereferencing), and at collection accesses; neither of them is expected to be noticeable (except in some very performance-critical code).</p>

<p>Generalizing this point further, we can split our code base into a small performance critical part (which weâ€™ll handle without our safety rules, but which is small enough to be scrutinized in a less formal manner), and a large performance-agnostic part (which weâ€™ll handle according to the safety rules above); however, in practice, these lines will be usually very close to the lines between Infrastructure Code and (Re)Actor Code.</p>

<p>One important thing to keep in mind when writing those Infrastructure objects which are intended to be called from (Re)Actors is ensuring that theyâ€™re safe even after their destructor is called (as discussed in the (*) paragraph above). On the other hand, if our object follows our safety rules above, this will be achieved automagically.</p>

<h2>All our rules are very local, which enables automated checks</h2>

<p>One further very important property of our safety rules is that </p>

<p class="blockquote"><em>theyâ€™re very local.</em></p>

<p>Indeed, <em>all</em> the rules above can be validated within the scope <em>of one single function</em>. In other words, it is possible to find whether our function <em>f()</em> is compliant with our safety rules using function <em>f()</em> and only function <em>f()</em>.</p>

<p>This not only allows for simple code reviews, but also means that this process can be automated relatively easily. Implementing such a tool is a different story (and it is still going to take a while) but is perfectly feasible (well, as long as we find a tool to parse C++ and get some kind of AST, but these days at least Clang does provide this kind of functionality).</p>

<p>As soon as such an automated check tool is implemented, development will become a breeze:</p>

<ul>
	<li>We separate our code into â€˜safeâ€™ code and â€˜unsafeâ€™ code (usually, though not strictly necessary, along the lines of the <code>(Re)Actor::react()</code>).</li>

	<li>For â€˜safeâ€™ code, such an automated check tool becomes a part of the build</li>

	<li>As a result, as long as â€˜unsafeâ€™ code is not changed (i.e. only â€˜safeâ€™ code is changed) there can be no possible regressions which can cause memory corruptions. </li>
</ul>

<p>While this is not a real â€˜silver bulletâ€™ (nothing really is â€“ in fact, the safety of theoretically safe languages also hinges on the safety of their compilers and standard libraries), this approach is expected to improve memory safety of the common business-level code by orders of magnitude (and even if your code is already perfectly safe, this approach will provide all the necessary peace of mind with regards to safety). </p>

<h2>Conclusion</h2>

<p>Thatâ€™s pretty much it â€“ we DID get a perfectly usable C++ dialect which is also 100% safe against memory corruption and against memory leaks. BTW, if necessary our approach can easily be extended to a more flexible model which relies on semantics similar to that of <code>std:shared_ptr&lt;&gt;</code> and <code>std::weak_ptr&lt;&gt;</code>; while I am not a fan of reference-counted semantics (from my experience, reference counting causes much more trouble than it is worth â€“ and simplistic â€˜owningâ€™ pointers are more straightforward and are perfectly usable for millions of LOC projects) â€“ it is perfectly feasible to implement shared ownership along the same lines as discussed above; the only substantial twist on this way is that as  <code>std::shared_ptr&lt;&gt;</code> (unlike our model above) does allow for circular references and resulting memory leaks, we will probably need to detect them (which can be done, for example, by running some kind of incremental garbage collection at those points where weâ€™re waiting for the input, sitting outside of <code>Reactor::react()</code>).</p>

<p>Phew. BTW, as the whole thing is quite complicated, please make sure to email me if you find any problem with the approach above (while Iâ€™m sure that it is possible to achieve safety along the lines discussed above, C++ is complicated enough we <em>might</em> need another restriction or two on this method).</p>

<p><img src="/content/images/journals/ol140/Ignatchenko/Ignatchenko-01.jpg" /></p>

<h2>References</h2>

<p class="bibliomixed"><a id="[Loganberry04]"></a>[Loganberry04] David â€˜Loganberryâ€™, Frithaes! â€“ an Introduction to Colloquial Lapine!, <a href="http://bitsnbobstones.watershipdown.org/lapine/overview.html">http://bitsnbobstones.watershipdown.org/lapine/overview.html</a></p>

<p class="bibliomixed"><a id="[NoBugs17]"></a>[NoBugs17] â€˜No Bugsâ€™ Hare, â€˜Allocator for (Re)Actors with Optional Kinda-Safety and Relocationâ€™, <em>Overload</em> #139, Jun 2017</p>

<h2>Acknowledgement</h2>
<p>Cartoon by Sergey Gordeev from Gordeev Animation Graphics, Prague</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
