Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r56241 - trunk/libs/serialization/doc
From: ramey_at_[hidden]
Date: 2009-09-16 00:49:21


Author: ramey
Date: 2009-09-16 00:49:20 EDT (Wed, 16 Sep 2009)
New Revision: 56241
URL: http://svn.boost.org/trac/boost/changeset/56241

Log:
Updated documentation to explain compile-time errors and warnings
Text files modified:
   trunk/libs/serialization/doc/contents.html | 1
   trunk/libs/serialization/doc/rationale.html | 220 ----------------------------------------
   2 files changed, 0 insertions(+), 221 deletions(-)

Modified: trunk/libs/serialization/doc/contents.html
==============================================================================
--- trunk/libs/serialization/doc/contents.html (original)
+++ trunk/libs/serialization/doc/contents.html 2009-09-16 00:49:20 EDT (Wed, 16 Sep 2009)
@@ -317,7 +317,6 @@
     <dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#serialization">The term "serialization" is preferred to "persistence"</a></dt>
     <dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#archives">Archives are not streams</a></dt>
     <dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#typeid"><code style="white-space: normal">typeid</code> information is not included in archives</a></dt>
- <dt><img style="display:none" src="dot.gif"><a target="detail" href="rationale.html#trap">Compile time trap when saving a non-const value</a></dt>
   </dl></div></dd>
 
   <dt><img style="display:none" src="plus.gif" id="todo"><a target="detail" href="todo.html">To Do</a></dt>

Modified: trunk/libs/serialization/doc/rationale.html
==============================================================================
--- trunk/libs/serialization/doc/rationale.html (original)
+++ trunk/libs/serialization/doc/rationale.html 2009-09-16 00:49:20 EDT (Wed, 16 Sep 2009)
@@ -110,226 +110,6 @@
 In effect, <code style="white-space: normal">export</code> generates a portable equivalent to
 <code style="white-space: normal">typeid</code> information.
 
-<h2><a name="trap"></a>Compile time trap when saving a non-const value</h2>
-</p>
-The following code will fail to compile. The failure will occur on a line with a
-<code style="white-space: normal">BOOST_STATIC_ASSERT</code>.
-Here, we refer to this as a compile time trap.
-<code style="white-space: normal"><pre>
-T t;
-ar &lt;&lt; t;
-</pre></code>
-
-unless the tracking_level serialization trait is set to "track_never". The following
-will compile without problem:
-
-<code style="white-space: normal"><pre>
-const T t
-ar &lt;&lt; t;
-</pre></code>
-
-Likewise, the following code will trap at compile time:
-
-<code style="white-space: normal"><pre>
-T * t;
-ar >> t;
-</pre></code>
-
-if the tracking_level serialization trait is set to "track_never".
-<p>
-
-This behavior has been contraversial and may be revised in the future. The criticism
-is that it will flag code that is in fact correct and force users to insert
-<code style="white-space: normal">const_cast</code>. My view is that:
-<ul>
- <li>The trap is useful in detecting a certain class of programming errors.
- <li>Such errors would otherwise be difficult to detect.
- <li>The incovenience caused by including this trap is very small in relation
- to its benefits.
-</ul>
-
-The following case illustrates my position. It was originally used as an example in the
-mailing list by Peter Dimov.
-
-<code style="white-space: normal"><pre>
-class construct_from
-{
- ...
-};
-
-void main(){
- ...
- Y y;
- construct_from x(y);
- ar &lt;&lt; x;
-}
-</pre></code>
-
-Suppose that there is no trap as described above.
-<ol>
- <li>this example compiles and executes fine. No tracking is done because
- construct_from has never been serialized through a pointer. Now some time
- later, the next programmer(2) comes along and makes an enhancement. He
- wants the archive to be sort of a log.
-
-<code style="white-space: normal"><pre>
-void main(){
- ...
- Y y;
- construct_from x(y);
- ar &lt;&lt; x;
- ...
- x.f(); // change x in some way
- ...
- ar &lt;&lt; x
-}
-</pre></code>
- <p>
- Again no problem. He gets two different of copies in the archive, each one is different.
- That is he gets exactly what he expects and is naturally delighted.
- <p>
- <li>Now sometime later, a third programmer(3) sees construct_from and says -
- oh cool, just what I need. He writes a function in a totally disjoint
- module. (The project is so big, he doesn't even realize the existence of
- the original usage) and writes something like:
-
-<code style="white-space: normal"><pre>
-class K {
- shared_ptr &lt;construct_from&gt; z;
- template &lt;class Archive&gt;
- void serialize(Archive & ar, const unsigned version){
- ar &lt;&lt; z;
- }
-};
-</pre></code>
-
- <p>
- He builds and runs the program and tests his new functionality. It works
- great and he's delighted.
- <p>
- <li>Things continue smoothly as before. A month goes by and it's
- discovered that when loading the archives made in the last month (reading the
- log). Things don't work. The second log entry is always the same as the
- first. After a series of very long and increasingly acrimonius email exchanges,
-its discovered
- that programmer (3) accidently broke programmer(2)'s code .This is because by
- serializing via a pointer, the "log" object now being tracked. This is because
- the default tracking behavior is "track_selectively". This means that class
- instances are tracked only if they are serialized through pointers anywhere in
- the program. Now multiple saves from the same address result in only the first one
- being written to the archive. Subsequent saves only add the address - even though the
- data might have been changed. When it comes time to load the data, all instances of the log record show the same data.
- In this way, the behavior of a functioning piece of code is changed due the side
- effect of a change in an otherwise disjoint module.
- Worse yet, the data has been lost and cannot not be now recovered from the archives.
- People are really upset and disappointed with boost (at least the serialization system).
- <p>
- <li>
- After a lot of investigation, it's discovered what the source of the problem
- and class construct_from is marked "track_never" by including:
-<code style="white-space: normal"><pre>
-BOOST_CLASS_TRACKING(construct_from, track_never)
-</pre></code>
- <li>Now everything works again. Or - so it seems.
- <p>
- <li><code style="white-space: normal">shared_ptr&lt;construct_from&gt;</code>
-is not going to have a single raw pointer shared amongst the instances. Each loaded
-<code style="white-space: normal">shared_ptr&lt;construct_from&gt;</code> is going to
-have its own distinct raw pointer. This will break
-<code style="white-space: normal">shared_ptr</code> and cause a memory leak. Again,
-The cause of this problem is very far removed from the point of discovery. It could
-well be that the problem is not even discovered until after the archives are loaded.
-Now we not only have difficult to find and fix program bug, but we have a bunch of
-invalid archives and lost data.
-</ol>
-
-Now consider what happens when the trap is enabled:.
-
-<ol>
- <p>
- <li>Right away, the program traps at
-<code style="white-space: normal"><pre>
-ar &lt;&lt; x;
-</pre></code>
- <p>
- <li>The programmer curses (another %^&*&* hoop to jump through). If he's in a
- hurry (and who isn't) and would prefer not to <code style="white-space: normal">const_cast</code>
- - because it looks bad. So he'll just make the following change an move on.
-<code style="white-space: normal"><pre>
-Y y;
-const construct_from x(y);
-ar &lt;&lt; x;
-</pre></code>
- <p>
- Things work fine and he moves on.
- <p>
- <li>Now programer (2) wants to make his change - and again another
- annoying const issue;
-<code style="white-space: normal"><pre>
-Y y;
-const construct_from x(y);
-...
-x.f(); // change x in some way ; compile error f() is not const
-...
-ar &lt;&lt; x
-</pre></code>
- <p>
- He's mildly annoyed now he tries the following:
- <ul>
- <li>He considers making f() a const - but presumable that shifts the const
- error to somewhere else. And his doesn't want to fiddle with "his" code to
- work around a quirk in the serializaition system
- <p>
- <li>He removes the <code style="white-space: normal">const</code>
- from <code style="white-space: normal">const construct_from</code> above - damn now he
- gets the trap. If he looks at the comment code where the
- <code style="white-space: normal">BOOST_STATIC_ASSERT</code>
- occurs, he'll do one of two things
- <ol>
- <p>
- <li>This is just crazy. Its making my life needlessly difficult and flagging
- code that is just fine. So I'll fix this with a <code style="white-space: normal">const_cast</code>
- and fire off a complaint to the list and mabe they will fix it.
- In this case, the story branches off to the previous scenario.
- <p>
- <li>Oh, this trap is suggesting that the default serialization isn't really
- what I want. Of course in this particular program it doesn't matter. But
- then the code in the trap can't really evaluate code in other modules (which
- might not even be written yet). OK, I'll add the following to my
- construct_from.hpp to solve the problem.
-<code style="white-space: normal"><pre>
-BOOST_CLASS_TRACKING(construct_from, track_never)
-</pre></code>
- </ol>
- </ul>
- <p>
- <li>Now programmer (3) comes along and make his change. The behavior of the
- original (and distant module) remains unchanged because the
- <code style="white-space: normal">construct_from</code> trait has been set to
- "track_never" so he should always get copies and the log should be what we expect.
- <p>
- <li>But now he gets another trap - trying to save an object of a
- class marked "track_never" through a pointer. So he goes back to
- construct_from.hpp and comments out the
- <code style="white-space: normal">BOOST_CLASS_TRACKING</code> that
- was inserted. Now the second trap is avoided, But damn - the first trap is
- popping up again. Eventually, after some code restructuring, the differing
- requirements of serializating <code style="white-space: normal">construct_from</code>
- are reconciled.
-</ol>
-Note that in this second scenario
-<ul>
- <li>all errors are trapped at compile time.
- <li>no invalid archives are created.
- <li>no data is lost.
- <li>no runtime errors occur.
-</ul>
-
-It's true that these traps may sometimes flag code that is currently correct and
-that this may be annoying to some programmers. However, this example illustrates
-my view that these traps are useful and that any such annoyance is small price to
-pay to avoid particularly vexing programming errors.
-
 <!--
 <h2><a name="footnotes"></a>Footnotes</h2>
 <dl>


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk