    <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  :: Compile Time Assertions in C</title>
        <link>https://members.accu.org/index.php/journals/866</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">CVu Journal Vol 11, #3 - Apr 1999 + Programming Topics</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/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c132/">113</a>
                    (22)
<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/c65/">Programming</a>
                    (877)
<br />

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

                    -                        <a href="https://members.accu.org/index.php/journals/c132+65/">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;Compile Time Assertions in C</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 03 April 1999 13:15:30 +01:00 or Sat, 03 April 1999 13:15:30 +01:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e20" id="d0e20"></a></h2>
</div>
<p>C has a facility for checking dynamic assertions at run-time.
It's inside <tt class="filename">&lt;assert.h&gt;</tt> and its
called <tt class="function">assert()</tt>. <tt class=
"function">assert()</tt> is a macro, so why isn't it called
<tt class="function">ASSERT()</tt>? I don't know. Prior art no
doubt. Anyway, <tt class="function">assert()</tt> is a dynamic
runtime feature, you can only use it inside functions.</p>
<pre class="programlisting">
/* not inside a function, won't compile :-( */
assert(sizeof(int) * CHAR_BIT &gt;= 32);  
</pre>
<p>That's a pity because it would be nice if I could get the
compiler to check things like this automatically at compile time.
I've occasionally seen an attempt at a compile-time check like
this...</p>
<pre class="programlisting">
#if sizeof(int) * CHAR_BIT &lt; 32
#error People of Earth. Your attention please...
#endif
</pre>
<p>But this doesn't work. The C preprocessor is a glorified text
reformatter: it knows practically nothing about C. However, there
is a way to write this as a compile time assertion (and moving any
error trap to an earlier phase is a Good Thing) { yourself }...</p>
<pre class="programlisting">
#define COMPILE_TIME_ASSERT(expr)   char constraint[expr]
COMPILE_TIME_ASSERT(sizeof(int) * CHAR_BIT &gt;= 32);
</pre>
<p>What's is going on here? Well, the example preprocesses
to...</p>
<pre class="programlisting">
char constraint[sizeof(int) * CHAR_BIT &gt;= 32];
</pre>
<p>If the expression is true, (an int is at least 32 bits), the
expression will have a value of one, and constraint will be an
array of one char. If the assertion is false, (an int is less than
32 bits), the expression will have a value of zero, and constraint
will be an empty array. That's illegal, and you'll get a compile
time error. Viola, a compile time assertion &#9786; You can use it
inside and outside a function but you can't use it twice in the
same function, as you end up with a duplicate definition of the
variable called constraint. To solve that problem you could resort
to some convoluted macro trickery...</p>
<pre class="programlisting">
#define COMPILE_TIME_ASSERT(expr)       char UNIQUE_NAME[expr]
#define UNIQUE_NAME                     MAKE_NAME(__LINE__)
#define MAKE_NAME(line)                 MAKE_NAME2(line)
#define MAKE_NAME2(line)                constraint_ ## line
</pre>
<p>But this is pretty horrible. Also, you will probably get
warnings about unused variables. Let's take a step back for a
moment and think about why it works at all. It's because you have
to specify the size of an array as a compile time constant. The
formal grammar of a direct-declarator tells you this.</p>
<pre class="literallayout">
  direct-declarator:
    identifier
    ( declarator )
    direct-declarator [ constant-expression opt ]
    direct-declarator ( parameter-type-list )
    direct-declarator ( identifier-list opt )
</pre>
<p>I just piggy backed on this, using the constrait that the value
of the constant expression cannot (in this context) be zero. A
natural question (to the curious) is what other parts of the formal
grammer require a constant expression. Well, first off there is the
value of an enumeration-constant</p>
<pre class="literallayout">
  enumerator:
    enumeration-constant
    enumeration-constant = constant-expression
</pre>
<p>However, I can't use this because there are no useful
constraints in this context. Another one is the size of a
bit-field.</p>
<pre class="literallayout">
  struct-declarator:
    declarator
    declarator opt : constant-expression
</pre>
<p>And reading the constraints of a bit field I see that if the
width of a bit-field is zero the declaration cannot have a
declarator. In other words this is legal</p>
<pre class="programlisting">
  struct x { unsigned int : 0; }
</pre>
<p>but this is not:</p>
<pre class="programlisting">
  struct x { unsigned int bf : 0; }
</pre>
<p>This suggests another way to create a compile time assertion</p>
<pre class="programlisting">
#define COMPILE_TIME_ASSERT(expr)   struct x { unsigned int bf : expr; }
COMPILE_TIME_ASSERT(sizeof(int) * CHAR_BIT &gt;= 32);
</pre>
<p>Trying this we again get duplicate definitions, not of a
variable this time, but of the type struct x. However we can fix
this by creating an anonymous struct.</p>
<pre class="programlisting">
#define COMPILE_TIME_ASSERT(expr)   struct { unsigned int bf : expr; }
</pre>
<p>This works. However, now you'll probably get warnings about the
unused untagged <tt class="literal">struct</tt>. There is one last
bit of grammar that uses a constant-expression. The humble switch
statement.</p>
<pre class="literallayout">
  labelled-statement:
    identifier : statement
    case constant-expression : statement
    default : statement
</pre>
<p>It's well known that you can't have two cases labels with the
same constant. The following will not compile.</p>
<pre class="programlisting">
  switch (0)
  {
  case 0:
  case 0:;
  }
</pre>
<p>So, here's yet another way to create a compile time assertion.
This time we don't create a dummy variable, or a dummy type, but a
dummy statement. A dummy switch statement.</p>
<pre class="programlisting">
#define COMPILE_TIME_ASSERT(pred)       switch(0){case 0:case pred:;}
COMPILE_TIME_ASSERT(sizeof(int) * CHAR_BIT &gt;= 32);
</pre>
<p>If pred evaluates to true (i.e., 1) then the case labels will be
0 and 1. Different; Ok. If pred evaluates to false (i.e., 0) then
the case labels will be 0 and 0. The same; Compile time error.
Viola. However, a switch statement cannot exist in the global
scope. So the last piece of the puzzle is to put the compile time
assertions inside a function.</p>
<pre class="programlisting">
#include &lt;limits.h&gt;
#define COMPILE_TIME_ASSERT(pred)       switch(0){case 0:case pred:;}
#define ASSERT_MIN_BITSIZE(type,size)        \
  COMPILE_TIME_ASSERT(sizeof(type) * CHAR_BIT &gt;= size)
#define ASSERT_EXACT_BITSIZE(type,size)       \
  COMPILE_TIME_ASSERT(sizeof(type) * CHAR_BIT == size)
void compile_time_assertions(void)
{
  ASSERT_MIN_BITSIZE(char,  8);
  ASSERT_MIN_BITSIZE(int,  16);
  ASSERT_EXACT_BITSIZE(long, 32);
}
</pre></div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e104" id="d0e104"></a>Editor's
Comments</h2>
</div>
<p>I have a couple of problems with the above. The biggest one is
that anyone doing maintenance better be a pretty good C programmer.
Anyone less than that is not going to be able to distinguish this
kind of arcane code from the awful rubbish that represents the
efforts of so many 'too clever for their own good' coders.</p>
<p>The second one is that you may have to throw the ISO compliance
switch to shut down vendor provided extensions. That would be fine
except that at least one well known vendors compiler will then
generate thousands of warnings, errors etc for its own library
code.</p>
<p>Thirdly it could be dependent on the version of the C standard
you are using (and I have not checked, but it might fail if you are
using your compiler in C++ mode).</p>
</div>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
