<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Where&#039;s Walden? &#187; assertion</title>
	<atom:link href="http://whereswalden.com/tag/assertion/feed/" rel="self" type="application/rss+xml" />
	<link>http://whereswalden.com</link>
	<description>Mozilla, politics, economics, law, backpacking, cycling, and other random desiderata</description>
	<lastBuildDate>Thu, 03 May 2012 09:13:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Introducing mozilla/Assertions.h to mfbt</title>
		<link>http://whereswalden.com/2011/12/26/introducing-mozillaassertions-h-to-mfbt/</link>
		<comments>http://whereswalden.com/2011/12/26/introducing-mozillaassertions-h-to-mfbt/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 17:17:34 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[assertion]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[mfbt]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[MOZ_ALWAYS_FALSE]]></category>
		<category><![CDATA[MOZ_ALWAYS_TRUE]]></category>
		<category><![CDATA[MOZ_ASSERT]]></category>
		<category><![CDATA[MOZ_ASSERT_IF]]></category>
		<category><![CDATA[MOZ_NOT_REACHED]]></category>
		<category><![CDATA[MOZ_STATIC_ASSERT]]></category>
		<category><![CDATA[static assertion]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=3639</guid>
		<description><![CDATA[Recently I landed changes to the Mozilla Framework Based on Templates (mfbt) implementing Assertions.h, the new canonical assertions implementation in C/C++ Mozilla code. Runtime assertions Using assertions, a developer can efficiently detect when his code goes awry because internal invariants were broken. Mozilla has many assertion facilities. NS_ASSERTION is the oldest, but unfortunately it can [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I landed changes to the Mozilla Framework Based on Templates (<a href="https://developer.mozilla.org/en/mfbt"><abbr title="Mozilla Framework Based on Templates">mfbt</abbr></a>) implementing <a href="http://mxr.mozilla.org/mozilla-central/source/mfbt/Assertions.h"><code>Assertions.h</code></a>, the new canonical assertions implementation in C/C++ Mozilla code.</p>
<h2>Runtime assertions</h2>
<p>Using assertions, a developer can efficiently detect when his code goes awry because internal invariants were broken.  Mozilla has many assertion facilities.  <code>NS_ASSERTION</code> is the oldest, but unfortunately it can be ignored, and therefore historically has been.  We later introduced <code>NS_ABORT_IF_FALSE</code> as as an actual assertion that fails hard, and it&#8217;s now widely used.  But it&#8217;s quite unwieldy, and it can&#8217;t be used by code that doesn&#8217;t want to depend on <abbr title="Cross-platform component object model">XPCOM</abbr>.  (Who would?)</p>
<p>mfbt addresses latent concerns with existing runtime assertions by introducing <code>MOZ_ASSERT</code>, <code>MOZ_ASSERT_IF</code>, <code>MOZ_ALWAYS_TRUE</code>, <code>MOZ_ALWAYS_FALSE</code>, and <code>MOZ_NOT_REACHED</code> macros to make performing true assertions dead simple.</p>
<h3><code>MOZ_ASSERT(expr)</code> and <code>MOZ_ASSERT_IF(ifexpr, expr)</code></h3>
<p><code>MOZ_ASSERT(expr)</code> is straightforward: pass an expression as its sole argument, and in debug builds, if that expression is falsy, the assertion fails and execution halts in a debuggable way.</p>
<pre class="code" data-language="c++">
#include "mozilla/Assertions.h"

void frobnicate(Thing* thing)
{
  MOZ_ASSERT(thing);
  thing->frob();
}
</pre>
<p><code>MOZ_ASSERT_IF(ifexpr, expr)</code> addresses the case when you want to assert something, where the check to decide whether to assert isn&#8217;t otherwise needed.  You&#8217;d rather not muddy up your code by adding an <code>#ifdef</code> and <code>if</code> statement around your assertion.  (<code>MOZ_ASSERT(!ifexpr || expr)</code> is a workaround, but it&#8217;s not very readable.)  SpiderMonkey&#8217;s experience suggests Mozilla code will get good mileage from <code>MOZ_ASSERT_IF</code>.</p>
<pre class="code" data-language="c++">
#include "mozilla/Assertions.h"

class Error
{
    const char* optionalDescription;

  public:
    /* If specified, desc must not be empty. */
    Error(const char* desc = NULL)
    {
      MOZ_ASSERT_IF(desc != NULL, desc[0] != '\0');
      optionalDescription = desc;
    }
};
</pre>
<h3><code>MOZ_ALWAYS_TRUE(expr)</code> and <code>MOZ_ALWAYS_FALSE(expr)</code></h3>
<p>Sometimes the expression for an assertion must always be executed for its side effects, and it can&#8217;t just be executed in debug builds.  <code>MOZ_ALWAYS_TRUE(expr)</code> and <code>MOZ_ALWAYS_FALSE(expr)</code> support this idiom.  These macros always evaluate their argument, and in debug builds that argument is asserted truthy or falsy.</p>
<pre class="code" data-language="c++">
#include "mozilla/Assertions.h"

/* JS_ValueToBoolean was fallible but no longer is. */
MOZ_ALWAYS_TRUE(JS_ValueToBoolean(cx, v, &#038;b));
</pre>
<h3><code>MOZ_NOT_REACHED(reason)</code></h3>
<p><code>MOZ_NOT_REACHED(reason)</code> indicates that the given point can&#8217;t be reached during execution: simply hitting it is a bug.  (Think of it as a more-explicit form of asserting <code>false</code>.)  It takes as an argument an explanation of why that point shouldn&#8217;t have been reachable.</p>
<pre class="code" data-language="c++">
#include "mozilla/Assertions.h"

// ...in a language parser...
void handle(BooleanLiteralNode node)
{
  if (node.isTrue())
    handleTrueLiteral();
  else if (node.isFalse())
    handleFalseLiteral();
  else
    MOZ_NOT_REACHED("boolean literal that's not true or false?");
}
</pre>
<h2>Compile-time assertions</h2>
<p>Most assertions must happen at runtime.  But some assertions are static, depending only on constants, and could be checked during compilation.  A compile time check is better than a runtime check: the developer need not ensure a test exercises that code, because the compiler itself enforces the assertion.  Properly crafted static assertions can never be unwittingly broken.</p>
<h3><code>MOZ_STATIC_ASSERT(cond, reason)</code></h3>
<p><code>MOZ_STATIC_ASSERT(cond, reason)</code> asserts a condition at compile time.  In newer compilers, if the assertion fails, the compiler will also include <code>reason</code> in diagnostics.</p>
<pre class="code" data-language="c++">
#include "mozilla/Assertions.h"

struct S { ... };
MOZ_STATIC_ASSERT(sizeof(S) % sizeof(size_t) == 0,
                  "S should be a multiple of word size for efficiency");
</pre>
<p><code>MOZ_STATIC_ASSERT</code> is implemented with <a href="http://hg.mozilla.org/mozilla-central/file/45206fca898d/mfbt/Assertions.h#l62">an impressive pile of hacks</a> which should work perfectly everywhere &mdash; except, rarely, gcc 4.2 (the current OS X compiler) when compiling C++ code.  The failure mode requires <code>MOZ_STATIC_ASSERT</code> on line <var>N</var> not in an <code>extern "C"</code> code block and a second <code>MOZ_STATIC_ASSERT</code> on the <em>same</em> line <var>N</var> (in a different file) in an <code>extern "C"</code> block.  <em>And</em> those two files have to be used when compiling a single file, with the <code>extern "C"</code>&#8216;d assertion second.  This seems improbable, so we&#8217;ll risk it til we drop gcc 4.2 support.</p>
<h2>Possible improvements</h2>
<p><code>Assertions.h</code> is reasonably complete, but I have a few ideas I&#8217;ve been considering for improvements.  Let me know what you think of them in comments.</p>
<h3>Add an optional <code>reason</code> argument to <code>MOZ_ASSERT</code>, and maybe to <code>MOZ_ALWAYS_TRUE</code> and <code>MOZ_ALWAYS_FALSE</code></h3>
<p><code>MOZ_ASSERT</code> takes only the condition to test as an argument.  In contrast <code>NS_ASSERTION</code> and <code>NS_ABORT_IF_FALSE</code> take the condition and an explanatory string.  <code>MOZ_ASSERT</code>&#8216;s lack of explanation derives purely from its ancestry in the <code>JS_ASSERT</code> macro: it wasn&#8217;t deliberate.</p>
<p>Would it be helpful if <code>MOZ_ASSERT</code>, <code>MOZ_ALWAYS_TRUE</code>, and <code>MOZ_ALWAYS_FALSE</code> optionally took a reason?  (Optional because some assertions, <abbr title="exempli gratia, for example" lang="la">e.g.</abbr> many non-null assertions, are self-explanatory.)  We&#8217;d have to disable assertions for compilers not implementing variadic macros (I think our supported compilers implement them), or <em>possibly</em> lose the condition expression in the assertion failure message.  A reason would make it easier to convert existing <code>NS_ABORT_IF_FALSE</code>s to <code>MOZ_ASSERT</code>s.  Should we add an optional second argument to <code>MOZ_ASSERT</code> and the others?</p>
<h3>Include <code>__assume(0)</code> or <code>__builtin_unreachable()</code> in <code>MOZ_NOT_REACHED</code></h3>
<p><a href="http://clang.llvm.org/docs/LanguageExtensions.html#__builtin_unreachable"><code>__builtin_unreachable()</code></a> and <a href="http://msdn.microsoft.com/en-us/library/1b3fsfxw.aspx"><code>__assume(0)</code></a> inform the compiler that subsequent code can&#8217;t be executed, providing optimization opportunities.  It&#8217;s unclear how this affects debugging feedback like stack traces.  If the optimizations destroy Breakpad-ability, that may be too big a loss.  More research is needed here.</p>
<p>Another possibility might be to use <a href="http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-g_t_005f_005fbuiltin_005ftrap-3216"><code>__builtin_trap()</code></a>.  This may not communicate an optimization opportunity comparable to that provided by the other two options.  (It can&#8217;t be equally informative because execution must be able to continue past a trap.  Thus the two have different impacts on variable lifetimes.  Whether <code>__builtin_trap</code> otherwise communicates &#8220;unlikelihood&#8221; well enough isn&#8217;t clear.)  Perhaps <code>__builtin_trap</code> could be used in debug builds, and <code>__builtin_unreachable</code> could be used in optimized builds.  Again: more research needed.</p>
<h3>Use C11&#8242;s <code>_Static_assert</code> in <code>MOZ_STATIC_ASSERT</code></h3>
<p>New editions of C and C++ include built-in static assertion syntax.  <code>MOZ_STATIC_ASSERT</code> expands to C++11&#8242;s <code>static_assert(2 + 2 == 4, "ya rly")</code> syntax when possible.  It could be made to expand to C11&#8242;s <code>_Static_assert('A' == 'A', "no wai")</code> syntax in some other cases, but frankly I don&#8217;t hack enough C code to care as long as the static assertion actually happens.  <img src='http://whereswalden.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />   This is <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=713531">bug 713531</a> if you&#8217;re interested in investigating.</p>
<h2>Want more information?</h2>
<p>Read <a href="http://mxr.mozilla.org/mozilla-central/source/mfbt/Assertions.h"><code>Assertions.h</code></a>.  mfbt code has a high standard for code comments in interface descriptions, and for file names (the current <code>Util.h</code> being a notable exception <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=713082">which will be fixed</a>).  We want it to be reasonably obvious where to find what you need and how to use it by skimming <a href="http://mxr.mozilla.org/mozilla-central/source/mfbt/"><code>mfbt/</code></a>&#8216;s contents and then skimming a few files&#8217; contents.  Good comments are key to that.  You should find <code>Assertions.h</code> quite readable; please <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Core&amp;product=MFBT">file a bug</a> if you have improvements to suggest.</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2011/12/26/introducing-mozillaassertions-h-to-mfbt/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>A reminder: NS_ABORT_IF_FALSE is the new NS_ASSERTION</title>
		<link>http://whereswalden.com/2009/01/04/a-reminder-ns_abort_if_false-is-the-new-ns_assertion/</link>
		<comments>http://whereswalden.com/2009/01/04/a-reminder-ns_abort_if_false-is-the-new-ns_assertion/#comments</comments>
		<pubDate>Mon, 05 Jan 2009 05:39:45 +0000</pubDate>
		<dc:creator>Jeff</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[assertion]]></category>
		<category><![CDATA[mozilla]]></category>

		<guid isPermaLink="false">http://whereswalden.com/?p=129</guid>
		<description><![CDATA[If you&#8217;re adding assertions to Mozilla code, don&#8217;t use NS_ASSERTION, and do use NS_ABORT_IF_FALSE. That is all.]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re adding assertions to Mozilla code, <em>don&#8217;t</em> use <code>NS_ASSERTION</code>, and <em>do</em> use <code>NS_ABORT_IF_FALSE</code>.  That is all.</p>
]]></content:encoded>
			<wfw:commentRss>http://whereswalden.com/2009/01/04/a-reminder-ns_abort_if_false-is-the-new-ns_assertion/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

