Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/doc/html/boost_staticassert.html @ 12

Last change on this file since 12 was 12, checked in by landauf, 18 years ago

added boost

File size: 19.1 KB
Line 
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
4<title>Chapter 10. Boost.StaticAssert</title>
5<link rel="stylesheet" href="boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.69.1">
7<link rel="start" href="index.html" title="The Boost C++ Libraries">
8<link rel="up" href="libraries.html" title="Part I. The Boost C++ Libraries">
9<link rel="prev" href="signals/tests.html" title="Testsuite">
10<link rel="next" href="boost_staticassert/how.html" title=" How it works">
11</head>
12<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
13<table cellpadding="2" width="100%">
14<td valign="top"><img alt="boost.png (6897 bytes)" width="277" height="86" src="../../boost.png"></td>
15<td align="center"><a href="../../index.htm">Home</a></td>
16<td align="center"><a href="../../libs/libraries.htm">Libraries</a></td>
17<td align="center"><a href="../../people/people.htm">People</a></td>
18<td align="center"><a href="../../more/faq.htm">FAQ</a></td>
19<td align="center"><a href="../../more/index.htm">More</a></td>
20</table>
21<hr>
22<div class="spirit-nav">
23<a accesskey="p" href="signals/tests.html"><img src="images/prev.png" alt="Prev"></a><a accesskey="u" href="libraries.html"><img src="images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="images/home.png" alt="Home"></a><a accesskey="n" href="boost_staticassert/how.html"><img src="images/next.png" alt="Next"></a>
24</div>
25<div class="chapter" lang="en">
26<div class="titlepage"><div>
27<div><h2 class="title">
28<a name="boost_staticassert"></a>Chapter 10. Boost.StaticAssert</h2></div>
29<div><div class="author"><h3 class="author">
30<span class="firstname">John</span> <span class="surname">Maddock</span>
31</h3></div></div>
32<div><div class="author"><h3 class="author">
33<span class="firstname">Steve</span> <span class="surname">Cleary</span>
34</h3></div></div>
35<div><p class="copyright">Copyright © 2000, 2005 Steve Cleary and John Maddock</p></div>
36<div><div class="legalnotice">
37<a name="id2740482"></a><p>
38        Distributed under the Boost Software License, Version 1.0.
39        (See accompanying file LICENSE_1_0.txt or copy at
40        <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
41            http://www.boost.org/LICENSE_1_0.txt
42        </a>)
43   
44      </p>
45</div></div>
46</div></div>
47<div class="toc">
48<p><b>Table of Contents</b></p>
49<dl>
50<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.intro"> Overview and Tutorial</a></span></dt>
51<dd><dl>
52<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.namespace"> Use at namespace scope.</a></span></dt>
53<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.function"> Use at function scope</a></span></dt>
54<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.class"> Use at class scope</a></span></dt>
55<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.templates"> Use in templates</a></span></dt>
56</dl></dd>
57<dt><span class="section"><a href="boost_staticassert/how.html"> How it works</a></span></dt>
58<dt><span class="section"><a href="boost_staticassert/test.html"> Test Programs</a></span></dt>
59</dl>
60</div>
61<div class="section" lang="en">
62<div class="titlepage"><div><div><h3 class="title">
63<a name="boost_staticassert.intro"></a> Overview and Tutorial</h3></div></div></div>
64<div class="toc"><dl>
65<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.namespace"> Use at namespace scope.</a></span></dt>
66<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.function"> Use at function scope</a></span></dt>
67<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.class"> Use at class scope</a></span></dt>
68<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.templates"> Use in templates</a></span></dt>
69</dl></div>
70<p>
71The header <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code> supplies a single macro <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>,
72which generates a compile time error message if the integral-constant-expression <code class="computeroutput"><span class="identifier">x</span></code>
73is not true. In other words it is the compile time equivalent of the assert macro;
74this is sometimes known as a "compile-time-assertion", but will be called a
75"static assertion" throughout these docs. Note that if the condition is <code class="computeroutput"><span class="keyword">true</span></code>,
76then the macro will generate neither code nor data - and the macro can also
77be used at either namespace, class or function scope. When used in a template,
78the static assertion will be evaluated at the time the template is instantiated;
79this is particularly useful for validating template parameters.</p>
80<p>
81One of the aims of <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> is to generate readable error messages.
82These immediately tell the user that a library is being used in a manner that
83is not supported. While error messages obviously differ from compiler to compiler,
84but you should see something like:</p>
85<pre class="programlisting"><code class="literal"><span class="identifier">Illegal</span><span class="identifier"> use</span><span class="identifier"> of</span><span class="identifier"> STATIC_ASSERTION_FAILURE</span><span class="special">&lt;</span><span class="keyword">false</span><span class="special">&gt;</span></code></pre>
86<p>
87Which is intended to at least catch the eye!</p>
88<p>
89You can use <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> at any place where you can place a declaration,
90that is at class, function or namespace scope, this is illustrated by the
91following examples:</p>
92<div class="section" lang="en">
93<div class="titlepage"><div><div><h4 class="title">
94<a name="boost_staticassert.namespace"></a> Use at namespace scope.</h4></div></div></div>
95<p>
96The macro can be used at namespace scope, if there is some requirement must
97always be true; generally this means some platform specific requirement.
98Suppose we require that <code class="computeroutput"><span class="keyword">int</span></code> be at least a 32-bit integral type, and that <code class="computeroutput"><span class="keyword">wchar_t</span></code> 
99be an unsigned type. We can verify this at compile time as follows:</p>
100<pre class="programlisting"><code class="literal"><span class="preprocessor">#include</span><span class="special"> &lt;</span><span class="identifier">climits</span><span class="special">&gt;</span><span class="preprocessor">
101#include</span><span class="special"> &lt;</span><span class="identifier">cwchar</span><span class="special">&gt;</span><span class="preprocessor">
102#include</span><span class="special"> &lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span><span class="keyword">
103
104namespace</span><span class="identifier"> my_conditions</span><span class="special"> {</span><span class="identifier">
105
106   BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="keyword">sizeof</span><span class="special">(</span><span class="keyword">int</span><span class="special">)</span><span class="special"> *</span><span class="identifier"> CHAR_BIT</span><span class="special"> &gt;=</span><span class="number"> 32</span><span class="special">);</span><span class="identifier">
107   BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">WCHAR_MIN</span><span class="special"> &gt;=</span><span class="number"> 0</span><span class="special">);</span><span class="special">
108
109}</span><span class="comment"> // namespace my_conditions
110</span></code></pre>
111<p>
112The use of the namespace my_conditions here requires some comment.
113The macro <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> works by generating an typedef declaration,
114and since the typedef must have a name, the macro generates one automatically by
115mangling a stub name with the value of <span class="underline">_LINE</span>_. When <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> is
116used at either class or function scope then each use of <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> 
117is guaranteed to produce a name unique to that scope (provided you only use
118the macro once on each line). However when used in a header at namespace
119scope, that namespace can be continued over multiple headers, each of which
120may have their own static assertions, and on the "same" lines, thereby generating
121duplicate declarations. In theory the compiler should silently ignore duplicate
122typedef declarations, however many do not do so (and even if they do they are
123entitled to emit warnings in such cases). To avoid potential problems, if you
124use <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> in a header and at namespace scope, then enclose
125them in a namespace unique to that header.</p>
126</div>
127<div class="section" lang="en">
128<div class="titlepage"><div><div><h4 class="title">
129<a name="boost_staticassert.function"></a> Use at function scope</h4></div></div></div>
130<p>
131The macro is typically used at function scope inside template functions,
132when the template arguments need checking. Imagine that we have an
133iterator-based algorithm that requires random access iterators.
134If the algorithm is instantiated with iterators that do not meet our
135requirements then an error will be generated eventually, but this may
136be nested deep inside several templates, making it hard for the user to
137determine what went wrong. One option is to add a static assertion at
138the top level of the template, in that case if the condition is not met,
139then an error will be generated in a way that makes it reasonably obvious to
140the user that the template is being misused.</p>
141<pre class="programlisting"><code class="literal"><span class="preprocessor">#include</span><span class="special"> &lt;</span><span class="identifier">iterator</span><span class="special">&gt;</span><span class="preprocessor">
142#include</span><span class="special"> &lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span><span class="preprocessor">
143#include</span><span class="special"> &lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">type_traits</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span><span class="keyword">
144
145template</span><span class="special"> &lt;</span><span class="keyword">class</span><span class="identifier"> RandomAccessIterator</span><span class="special"> &gt;</span><span class="identifier">
146RandomAccessIterator</span><span class="identifier"> foo</span><span class="special">(</span><span class="identifier">RandomAccessIterator</span><span class="identifier"> from</span><span class="special">,</span><span class="identifier"> RandomAccessIterator</span><span class="identifier"> to</span><span class="special">)</span><span class="special">
147{</span><span class="comment">
148   // this template can only be used with
149   // random access iterators...
150</span><span class="keyword">   typedef</span><span class="keyword"> typename</span><span class="identifier"> std</span><span class="special">::</span><span class="identifier">iterator_traits</span><span class="special">&lt;</span><span class="identifier"> RandomAccessIterator</span><span class="special"> &gt;::</span><span class="identifier">iterator_category</span><span class="identifier"> cat</span><span class="special">;</span><span class="identifier">
151   BOOST_STATIC_ASSERT</span><span class="special">((</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_convertible</span><span class="special">&lt;</span><span class="identifier">cat</span><span class="special">,</span><span class="keyword"> const</span><span class="identifier"> std</span><span class="special">::</span><span class="identifier">random_access_iterator_tag</span><span class="special">&amp;&gt;::</span><span class="identifier">value</span><span class="special">));</span><span class="comment">
152   //
153   // detail goes here...
154</span><span class="keyword">   return</span><span class="identifier"> from</span><span class="special">;</span><span class="special">
155}</span></code></pre>
156<p>
157A couple of footnotes are in order here: the extra set of parenthesis around the
158assert, is to prevent the comma inside the <code class="computeroutput"><span class="identifier">is_convertible</span></code> template being
159interpreted by the preprocessor as a macro argument separator; the target type
160for <code class="computeroutput"><span class="identifier">is_convertible</span></code> is a reference type, as some compilers have problems
161using <code class="computeroutput"><span class="identifier">is_convertible</span></code> when the conversion is via a user defined constructor
162(in any case there is no guarantee that the iterator tag classes are
163copy-constructible).</p>
164</div>
165<div class="section" lang="en">
166<div class="titlepage"><div><div><h4 class="title">
167<a name="boost_staticassert.class"></a> Use at class scope</h4></div></div></div>
168<p>
169The macro is typically used inside classes that are templates.
170Suppose we have a template-class that requires an unsigned integral type with
171at least 16-bits of precision as a template argument, we can achieve this
172using something like this:</p>
173<pre class="programlisting"><code class="literal"><span class="preprocessor">#include</span><span class="special"> &lt;</span><span class="identifier">climits</span><span class="special">&gt;</span><span class="preprocessor">
174#include</span><span class="special"> &lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span><span class="keyword">
175
176template</span><span class="special"> &lt;</span><span class="keyword">class</span><span class="identifier"> UnsignedInt</span><span class="special">&gt;</span><span class="keyword">
177class</span><span class="identifier"> myclass</span><span class="special">
178{</span><span class="keyword">
179private</span><span class="special">:</span><span class="identifier">
180   BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">UnsignedInt</span><span class="special">)</span><span class="special"> *</span><span class="identifier"> CHAR_BIT</span><span class="special"> &gt;=</span><span class="number"> 16</span><span class="special">);</span><span class="identifier">
181   BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">UnsignedInt</span><span class="special">&gt;::</span><span class="identifier">is_specialized</span><span class="special">
182                        &amp;&amp;</span><span class="identifier"> std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">UnsignedInt</span><span class="special">&gt;::</span><span class="identifier">is_integer</span><span class="special">
183                        &amp;&amp;</span><span class="special"> !</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">numeric_limits</span><span class="special">&lt;</span><span class="identifier">UnsignedInt</span><span class="special">&gt;::</span><span class="identifier">is_signed</span><span class="special">);</span><span class="keyword">
184public</span><span class="special">:</span><span class="comment">
185   /* details here */</span><span class="special">
186};</span></code></pre>
187</div>
188<div class="section" lang="en">
189<div class="titlepage"><div><div><h4 class="title">
190<a name="boost_staticassert.templates"></a> Use in templates</h4></div></div></div>
191<p>
192Normally static assertions when used inside a class or function template,
193will not be instantiated until the template in which it is used is instantiated. 
194However, there is one potential problem to watch out for: if the static assertion
195is not dependent upon one or more template parameters, then the compiler is
196permitted to evaluate the static assertion at the point it is first seen,
197irrespective of whether the template is ever instantiated, for example:</p>
198<pre class="programlisting"><code class="literal"><span class="keyword">template</span><span class="special"> &lt;</span><span class="keyword">class</span><span class="identifier"> T</span><span class="special">&gt;</span><span class="keyword">
199struct</span><span class="identifier"> must_not_be_instantiated</span><span class="special">
200{</span><span class="identifier">   
201   BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="keyword">false</span><span class="special">);</span><span class="special">
202};</span></code></pre>
203<p>
204Will produce a compiler error with some compilers (for example Intel 8.1
205or gcc 3.4), regardless of whether the template is ever instantiated.  A
206workaround in cases like this is to force the assertion to be dependent
207upon a template parameter:</p>
208<pre class="programlisting"><code class="literal"><span class="keyword">template</span><span class="special"> &lt;</span><span class="keyword">class</span><span class="identifier"> T</span><span class="special">&gt;</span><span class="keyword">
209struct</span><span class="identifier"> must_not_be_instantiated</span><span class="special">
210{</span><span class="comment">   
211   // this will be triggered if this type is instantiated
212</span><span class="identifier">   BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="keyword">sizeof</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span><span class="special"> ==</span><span class="number"> 0</span><span class="special">);</span><span class="special"> 
213};</span></code></pre>
214</div>
215</div>
216</div>
217<table width="100%"><tr>
218<td align="left"><small><p>Last revised: April 17, 2005 at 10:45:13 GMT</p></small></td>
219<td align="right"><small></small></td>
220</tr></table>
221<hr>
222<div class="spirit-nav">
223<a accesskey="p" href="signals/tests.html"><img src="images/prev.png" alt="Prev"></a><a accesskey="u" href="libraries.html"><img src="images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="images/home.png" alt="Home"></a><a accesskey="n" href="boost_staticassert/how.html"><img src="images/next.png" alt="Next"></a>
224</div>
225</body>
226</html>
Note: See TracBrowser for help on using the repository browser.