Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/doc/html/boost_staticassert.html @ 66

Last change on this file since 66 was 29, checked in by landauf, 16 years ago

updated boost from 1_33_1 to 1_34_1

File size: 20.1 KB
Line 
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
4<title>Chapter 13. Boost.StaticAssert</title>
5<link rel="stylesheet" href="boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">
7<link rel="start" href="index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
8<link rel="up" href="libraries.html" title="Part I. The Boost C++ Libraries (BoostBook Subset)">
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 C++ Libraries" 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 13. 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="id1635481"></a><p>
38        Distributed under the Boost Software License, Version 1.0. (See accompanying
39        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
40        http://www.boost.org/LICENSE_1_0.txt </a>)
41      </p>
42</div></div>
43</div></div>
44<div class="toc">
45<p><b>Table of Contents</b></p>
46<dl>
47<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.intro"> Overview and Tutorial</a></span></dt>
48<dd><dl>
49<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.namespace"> Use at namespace scope.</a></span></dt>
50<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.function"> Use at function scope</a></span></dt>
51<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.class"> Use at class scope</a></span></dt>
52<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.templates"> Use in templates</a></span></dt>
53</dl></dd>
54<dt><span class="section"><a href="boost_staticassert/how.html"> How it works</a></span></dt>
55<dt><span class="section"><a href="boost_staticassert/test.html"> Test Programs</a></span></dt>
56</dl>
57</div>
58<div class="section" lang="en">
59<div class="titlepage"><div><div><h2 class="title" style="clear: both">
60<a name="boost_staticassert.intro"></a> Overview and Tutorial</h2></div></div></div>
61<div class="toc"><dl>
62<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.namespace"> Use at namespace scope.</a></span></dt>
63<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.function"> Use at function scope</a></span></dt>
64<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.class"> Use at class scope</a></span></dt>
65<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.templates"> Use in templates</a></span></dt>
66</dl></div>
67<p>
68      This documentation is <a href="http://boost-consulting.com/vault/index.php?action=downloadfile&amp;filename=boost_static_assert-1.34.pdf&amp;directory=PDF%20Documentation&amp;" target="_top">also
69      available in printer-friendly PDF format</a>.
70    </p>
71<p>
72      The 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>
73      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>,
74      which generates a compile time error message if the integral-constant-expression
75      <code class="computeroutput"><span class="identifier">x</span></code> is not true. In other words
76      it is the compile time equivalent of the assert macro; this is sometimes known
77      as a "compile-time-assertion", but will be called a "static
78      assertion" throughout these docs. Note that if the condition is <code class="computeroutput"><span class="keyword">true</span></code>, then the macro will generate neither code
79      nor data - and the macro can also be used at either namespace, class or function
80      scope. When used in a template, the static assertion will be evaluated at the
81      time the template is instantiated; this is particularly useful for validating
82      template parameters.
83    </p>
84<p>
85      One of the aims of <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
86      is to generate readable error messages. These immediately tell the user that
87      a library is being used in a manner that is not supported. While error messages
88      obviously differ from compiler to compiler, but you should see something like:
89    </p>
90<pre class="programlisting">
91<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>
92</pre>
93<p>
94      Which is intended to at least catch the eye!
95    </p>
96<p>
97      You can use <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
98      at any place where you can place a declaration, that is at class, function
99      or namespace scope, this is illustrated by the following examples:
100    </p>
101<div class="section" lang="en">
102<div class="titlepage"><div><div><h3 class="title">
103<a name="boost_staticassert.namespace"></a> Use at namespace scope.</h3></div></div></div>
104<p>
105        The macro can be used at namespace scope, if there is some requirement must
106        always be true; generally this means some platform specific requirement.
107        Suppose we require that <code class="computeroutput"><span class="keyword">int</span></code>
108        be at least a 32-bit integral type, and that <code class="computeroutput"><span class="keyword">wchar_t</span></code>
109        be an unsigned type. We can verify this at compile time as follows:
110      </p>
111<pre class="programlisting">
112<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">climits</span><span class="special">&gt;</span>
113<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cwchar</span><span class="special">&gt;</span>
114<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">limits</span><span class="special">&gt;</span>
115<span class="preprocessor">#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>
116
117<span class="keyword">namespace</span> <span class="identifier">my_conditions</span> <span class="special">{</span>
118
119   <span class="identifier">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="keyword">int</span><span class="special">&gt;::</span><span class="identifier">digits</span> <span class="special">&gt;=</span> <span class="number">32</span><span class="special">);</span>
120   <span class="identifier">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>
121
122<span class="special">}</span> <span class="comment">// namespace my_conditions
123</span></pre>
124<p>
125        The use of the namespace my_conditions here requires some comment. The macro
126        <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> works
127        by generating an typedef declaration, and since the typedef must have a name,
128        the macro generates one automatically by mangling a stub name with the value
129        of <code class="computeroutput"><span class="identifier">__LINE__</span></code>. When <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> is used at either class
130        or function scope then each use of <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
131        is guaranteed to produce a name unique to that scope (provided you only use
132        the macro once on each line). However when used in a header at namespace
133        scope, that namespace can be continued over multiple headers, each of which
134        may have their own static assertions, and on the "same" lines,
135        thereby generating duplicate declarations. In theory the compiler should
136        silently ignore duplicate typedef declarations, however many do not do so
137        (and even if they do they are entitled to emit warnings in such cases). To
138        avoid potential problems, if you use <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
139        in a header and at namespace scope, then enclose them in a namespace unique
140        to that header.
141      </p>
142</div>
143<div class="section" lang="en">
144<div class="titlepage"><div><div><h3 class="title">
145<a name="boost_staticassert.function"></a> Use at function scope</h3></div></div></div>
146<p>
147        The macro is typically used at function scope inside template functions,
148        when the template arguments need checking. Imagine that we have an iterator-based
149        algorithm that requires random access iterators. If the algorithm is instantiated
150        with iterators that do not meet our requirements then an error will be generated
151        eventually, but this may be nested deep inside several templates, making
152        it hard for the user to determine what went wrong. One option is to add a
153        static assertion at the top level of the template, in that case if the condition
154        is not met, then an error will be generated in a way that makes it reasonably
155        obvious to the user that the template is being misused.
156      </p>
157<pre class="programlisting">
158<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iterator</span><span class="special">&gt;</span>
159<span class="preprocessor">#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>
160<span class="preprocessor">#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>
161
162<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">RandomAccessIterator</span> <span class="special">&gt;</span>
163<span class="identifier">RandomAccessIterator</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>
164<span class="special">{</span>
165   <span class="comment">// this template can only be used with
166</span>   <span class="comment">// random access iterators...
167</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>
168   <span class="identifier">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>
169   <span class="comment">//
170</span>   <span class="comment">// detail goes here...
171</span>   <span class="keyword">return</span> <span class="identifier">from</span><span class="special">;</span>
172<span class="special">}</span>
173</pre>
174<p>
175        A couple of footnotes are in order here: the extra set of parenthesis around
176        the assert, is to prevent the comma inside the <code class="computeroutput"><span class="identifier">is_convertible</span></code>
177        template being interpreted by the preprocessor as a macro argument separator;
178        the target type for <code class="computeroutput"><span class="identifier">is_convertible</span></code>
179        is a reference type, as some compilers have problems using <code class="computeroutput"><span class="identifier">is_convertible</span></code> when the conversion is via
180        a user defined constructor (in any case there is no guarantee that the iterator
181        tag classes are copy-constructible).
182      </p>
183</div>
184<div class="section" lang="en">
185<div class="titlepage"><div><div><h3 class="title">
186<a name="boost_staticassert.class"></a> Use at class scope</h3></div></div></div>
187<p>
188        The macro is typically used inside classes that are templates. Suppose we
189        have a template-class that requires an unsigned integral type with at least
190        16-bits of precision as a template argument, we can achieve this using something
191        like this:
192      </p>
193<pre class="programlisting">
194<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">climits</span><span class="special">&gt;</span>
195<span class="preprocessor">#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>
196
197<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">UnsignedInt</span><span class="special">&gt;</span>
198<span class="keyword">class</span> <span class="identifier">myclass</span>
199<span class="special">{</span>
200<span class="keyword">private</span><span class="special">:</span>
201   <span class="identifier">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">digits</span> <span class="special">&gt;=</span> <span class="number">16</span><span class="special">)</span>
202                        <span class="special">&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_specialized</span>
203                        <span class="special">&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>
204                        <span class="special">&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>
205<span class="keyword">public</span><span class="special">:</span>
206   <span class="comment">/* details here */</span>
207<span class="special">};</span>
208</pre>
209</div>
210<div class="section" lang="en">
211<div class="titlepage"><div><div><h3 class="title">
212<a name="boost_staticassert.templates"></a> Use in templates</h3></div></div></div>
213<p>
214        Normally static assertions when used inside a class or function template,
215        will not be instantiated until the template in which it is used is instantiated.
216        However, there is one potential problem to watch out for: if the static assertion
217        is not dependent upon one or more template parameters, then the compiler
218        is permitted to evaluate the static assertion at the point it is first seen,
219        irrespective of whether the template is ever instantiated, for example:
220      </p>
221<pre class="programlisting">
222<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>
223<span class="keyword">struct</span> <span class="identifier">must_not_be_instantiated</span>
224<span class="special">{</span>   
225   <span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="keyword">false</span><span class="special">);</span>
226<span class="special">};</span>
227</pre>
228<p>
229        Will produce a compiler error with some compilers (for example Intel 8.1
230        or gcc 3.4), regardless of whether the template is ever instantiated. A workaround
231        in cases like this is to force the assertion to be dependent upon a template
232        parameter:
233      </p>
234<pre class="programlisting">
235<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>
236<span class="keyword">struct</span> <span class="identifier">must_not_be_instantiated</span>
237<span class="special">{</span>   
238   <span class="comment">// this will be triggered if this type is instantiated
239</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> 
240<span class="special">};</span>
241</pre>
242</div>
243</div>
244</div>
245<table width="100%"><tr>
246<td align="left"><small><p>Last revised: May 09, 2007 at 17:20:56 GMT</p></small></td>
247<td align="right"><small></small></td>
248</tr></table>
249<hr>
250<div class="spirit-nav">
251<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>
252</div>
253</body>
254</html>
Note: See TracBrowser for help on using the repository browser.