• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2<html>
3<head>
4<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5<title>Chapter 37. Boost.StaticAssert</title>
6<link rel="stylesheet" href="../../doc/src/boostbook.css" type="text/css">
7<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
8<link rel="home" href="index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
9<link rel="up" href="libraries.html" title="Part I. The Boost C++ Libraries (BoostBook Subset)">
10<link rel="prev" href="boost/stacktrace/safe_dump_1_3_37_7_6_2_1_6.html" title="Function safe_dump_to">
11<link rel="next" href="boost_staticassert/how.html" title="How it works">
12</head>
13<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
14<table cellpadding="2" width="100%"><tr>
15<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../boost.png"></td>
16<td align="center"><a href="../../index.html">Home</a></td>
17<td align="center"><a href="../../libs/libraries.htm">Libraries</a></td>
18<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
19<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
20<td align="center"><a href="../../more/index.htm">More</a></td>
21</tr></table>
22<hr>
23<div class="spirit-nav">
24<a accesskey="p" href="boost/stacktrace/safe_dump_1_3_37_7_6_2_1_6.html"><img src="../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="libraries.html"><img src="../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="boost_staticassert/how.html"><img src="../../doc/src/images/next.png" alt="Next"></a>
25</div>
26<div class="chapter">
27<div class="titlepage"><div>
28<div><h2 class="title">
29<a name="boost_staticassert"></a>Chapter 37. Boost.StaticAssert</h2></div>
30<div><div class="author"><h3 class="author">
31<span class="firstname">John</span> <span class="surname">Maddock</span>
32</h3></div></div>
33<div><div class="author"><h3 class="author">
34<span class="firstname">Steve</span> <span class="surname">Cleary</span>
35</h3></div></div>
36<div><p class="copyright">Copyright © 2000, 2005 Steve Cleary and John Maddock</p></div>
37<div><div class="legalnotice">
38<a name="boost_staticassert.legal"></a><p>
39        Distributed under the Boost Software License, Version 1.0. (See accompanying
40        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">
41        http://www.boost.org/LICENSE_1_0.txt </a>)
42      </p>
43</div></div>
44</div></div>
45<div class="toc">
46<p><b>Table of Contents</b></p>
47<dl class="toc">
48<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.intro">Overview and Tutorial</a></span></dt>
49<dd><dl>
50<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.namespace">Use at namespace scope.</a></span></dt>
51<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.function">Use at function scope</a></span></dt>
52<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.class">Use at class scope</a></span></dt>
53<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.templates">Use in templates</a></span></dt>
54</dl></dd>
55<dt><span class="section"><a href="boost_staticassert/how.html">How it works</a></span></dt>
56<dt><span class="section"><a href="boost_staticassert/test.html">Test Programs</a></span></dt>
57</dl>
58</div>
59<p>
60    This manual is also available in <a href="http://sourceforge.net/projects/boost/files/boost-docs/" target="_top">printer
61    friendly PDF format</a>.
62  </p>
63<div class="section">
64<div class="titlepage"><div><div><h2 class="title" style="clear: both">
65<a name="boost_staticassert.intro"></a>Overview and Tutorial</h2></div></div></div>
66<div class="toc"><dl class="toc">
67<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.namespace">Use at namespace scope.</a></span></dt>
68<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.function">Use at function scope</a></span></dt>
69<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.class">Use at class scope</a></span></dt>
70<dt><span class="section"><a href="boost_staticassert.html#boost_staticassert.templates">Use in templates</a></span></dt>
71</dl></div>
72<p>
73      The header <code class="computeroutput"><span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span></code>
74      supplies two macros:
75    </p>
76<pre class="programlisting"><span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span>
77<span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span> <span class="identifier">msg</span><span class="special">)</span>
78</pre>
79<p>
80      Both generate a compile time error message if the integral-constant-expression
81      <code class="computeroutput"><span class="identifier">x</span></code> is not true. In other words,
82      they are the compile time equivalent of the assert macro; this is sometimes
83      known as a "compile-time-assertion", but will be called a "static
84      assertion" throughout these docs. Note that if the condition is <code class="computeroutput"><span class="keyword">true</span></code>, then the macros will generate neither
85      code nor data - and the macros can also be used at either namespace, class
86      or function scope. When used in a template, the static assertion will be evaluated
87      at the time the template is instantiated; this is particularly useful for validating
88      template parameters.
89    </p>
90<p>
91      If the C++0x <code class="computeroutput"><span class="keyword">static_assert</span></code> feature
92      is available, both macros will use it. For <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>,
93      the error message will be a stringized version of <code class="computeroutput"><span class="identifier">x</span></code>.
94      For <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span>
95      <span class="identifier">msg</span><span class="special">)</span></code>,
96      the error message will be the <code class="computeroutput"><span class="identifier">msg</span></code>
97      string.
98    </p>
99<p>
100      If the C++0x <code class="computeroutput"><span class="keyword">static_assert</span></code> feature
101      is not available, <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT_MSG</span><span class="special">(</span><span class="identifier">x</span><span class="special">,</span>
102      <span class="identifier">msg</span><span class="special">)</span></code>
103      will be treated as <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span></code>.
104    </p>
105<p>
106      The material that follows assumes the C++0x <code class="computeroutput"><span class="keyword">static_assert</span></code>
107      feature is not available.
108    </p>
109<p>
110      One of the aims of <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
111      is to generate readable error messages. These immediately tell the user that
112      a library is being used in a manner that is not supported. While error messages
113      obviously differ from compiler to compiler, but you should see something like:
114    </p>
115<pre class="programlisting"><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>
116</pre>
117<p>
118      Which is intended to at least catch the eye!
119    </p>
120<p>
121      You can use <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
122      at any place where you can place a declaration, that is at class, function
123      or namespace scope, this is illustrated by the following examples:
124    </p>
125<div class="section">
126<div class="titlepage"><div><div><h3 class="title">
127<a name="boost_staticassert.namespace"></a>Use at namespace scope.</h3></div></div></div>
128<p>
129        The macro can be used at namespace scope, if there is some requirement must
130        always be true; generally this means some platform specific requirement.
131        Suppose we require that <code class="computeroutput"><span class="keyword">int</span></code>
132        be at least a 32-bit integral type, and that <code class="computeroutput"><span class="keyword">wchar_t</span></code>
133        be an unsigned type. We can verify this at compile time as follows:
134      </p>
135<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">climits</span><span class="special">&gt;</span>
136<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">cwchar</span><span class="special">&gt;</span>
137<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">limits</span><span class="special">&gt;</span>
138<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
139
140<span class="keyword">namespace</span> <span class="identifier">my_conditions</span> <span class="special">{</span>
141
142   <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>
143   <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>
144
145<span class="special">}</span> <span class="comment">// namespace my_conditions</span>
146</pre>
147<p>
148        The use of the namespace my_conditions here requires some comment. The macro
149        <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code> works
150        by generating an typedef declaration, and since the typedef must have a name,
151        the macro generates one automatically by mangling a stub name with the value
152        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
153        or function scope then each use of <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
154        is guaranteed to produce a name unique to that scope (provided you only use
155        the macro once on each line). However when used in a header at namespace
156        scope, that namespace can be continued over multiple headers, each of which
157        may have their own static assertions, and on the "same" lines,
158        thereby generating duplicate declarations. In theory the compiler should
159        silently ignore duplicate typedef declarations, however many do not do so
160        (and even if they do they are entitled to emit warnings in such cases). To
161        avoid potential problems, if you use <code class="computeroutput"><span class="identifier">BOOST_STATIC_ASSERT</span></code>
162        in a header and at namespace scope, then enclose them in a namespace unique
163        to that header.
164      </p>
165</div>
166<div class="section">
167<div class="titlepage"><div><div><h3 class="title">
168<a name="boost_staticassert.function"></a>Use at function scope</h3></div></div></div>
169<p>
170        The macro is typically used at function scope inside template functions,
171        when the template arguments need checking. Imagine that we have an iterator-based
172        algorithm that requires random access iterators. If the algorithm is instantiated
173        with iterators that do not meet our requirements then an error will be generated
174        eventually, but this may be nested deep inside several templates, making
175        it hard for the user to determine what went wrong. One option is to add a
176        static assertion at the top level of the template, in that case if the condition
177        is not met, then an error will be generated in a way that makes it reasonably
178        obvious to the user that the template is being misused.
179      </p>
180<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">iterator</span><span class="special">&gt;</span>
181<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
182<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>
183
184<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>
185<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>
186                         <span class="identifier">RandomAccessIterator</span> <span class="identifier">to</span><span class="special">)</span>
187<span class="special">{</span>
188   <span class="comment">// this template can only be used with</span>
189   <span class="comment">// random access iterators...</span>
190   <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>
191         <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>
192   <span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span>
193      <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">is_convertible</span><span class="special">&lt;</span>
194         <span class="identifier">cat</span><span class="special">,</span>
195         <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>
196   <span class="comment">//</span>
197   <span class="comment">// detail goes here...</span>
198   <span class="keyword">return</span> <span class="identifier">from</span><span class="special">;</span>
199<span class="special">}</span>
200</pre>
201<p>
202        A couple of footnotes are in order here: the extra set of parenthesis around
203        the assert, is to prevent the comma inside the <code class="computeroutput"><span class="identifier">is_convertible</span></code>
204        template being interpreted by the preprocessor as a macro argument separator;
205        the target type for <code class="computeroutput"><span class="identifier">is_convertible</span></code>
206        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
207        a user defined constructor (in any case there is no guarantee that the iterator
208        tag classes are copy-constructible).
209      </p>
210</div>
211<div class="section">
212<div class="titlepage"><div><div><h3 class="title">
213<a name="boost_staticassert.class"></a>Use at class scope</h3></div></div></div>
214<p>
215        The macro is typically used inside classes that are templates. Suppose we
216        have a template-class that requires an unsigned integral type with at least
217        16-bits of precision as a template argument, we can achieve this using something
218        like this:
219      </p>
220<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">limits</span><span class="special">&gt;</span>
221<span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="keyword">static_assert</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
222
223<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>
224<span class="keyword">class</span> <span class="identifier">myclass</span>
225<span class="special">{</span>
226<span class="keyword">private</span><span class="special">:</span>
227   <span class="identifier">BOOST_STATIC_ASSERT_MSG</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">,</span> <span class="string">"myclass can only be specialized for types with numeric_limits support."</span><span class="special">);</span>
228   <span class="identifier">BOOST_STATIC_ASSERT_MSG</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> <span class="string">"Template argument UnsignedInt must have at least 16 bits precision."</span><span class="special">)</span>
229   <span class="identifier">BOOST_STATIC_ASSERT_MSG</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_integer</span><span class="special">,</span> <span class="string">"Template argument UnsignedInt must be an integer."</span><span class="special">);</span>
230   <span class="identifier">BOOST_STATIC_ASSERT_MSG</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="string">"Template argument UnsignedInt must not be signed."</span><span class="special">);</span>
231<span class="keyword">public</span><span class="special">:</span>
232   <span class="comment">/* details here */</span>
233<span class="special">};</span>
234</pre>
235</div>
236<div class="section">
237<div class="titlepage"><div><div><h3 class="title">
238<a name="boost_staticassert.templates"></a>Use in templates</h3></div></div></div>
239<p>
240        Normally static assertions when used inside a class or function template,
241        will not be instantiated until the template in which it is used is instantiated.
242        However, there is one potential problem to watch out for: if the static assertion
243        is not dependent upon one or more template parameters, then the compiler
244        is permitted to evaluate the static assertion at the point it is first seen,
245        irrespective of whether the template is ever instantiated, for example:
246      </p>
247<pre class="programlisting"><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>
248<span class="keyword">struct</span> <span class="identifier">must_not_be_instantiated</span>
249<span class="special">{</span>
250   <span class="identifier">BOOST_STATIC_ASSERT</span><span class="special">(</span><span class="keyword">false</span><span class="special">);</span>
251<span class="special">};</span>
252</pre>
253<p>
254        Will produce a compiler error with some compilers (for example Intel 8.1
255        or gcc 3.4), regardless of whether the template is ever instantiated. A workaround
256        in cases like this is to force the assertion to be dependent upon a template
257        parameter:
258      </p>
259<pre class="programlisting"><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>
260<span class="keyword">struct</span> <span class="identifier">must_not_be_instantiated</span>
261<span class="special">{</span>
262   <span class="comment">// this will be triggered if this type is instantiated</span>
263   <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>
264<span class="special">};</span>
265</pre>
266</div>
267</div>
268</div>
269<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
270<td align="left"></td>
271<td align="right"><div class="copyright-footer"></div></td>
272</tr></table>
273<hr>
274<div class="spirit-nav">
275<a accesskey="p" href="boost/stacktrace/safe_dump_1_3_37_7_6_2_1_6.html"><img src="../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="libraries.html"><img src="../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="index.html"><img src="../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="boost_staticassert/how.html"><img src="../../doc/src/images/next.png" alt="Next"></a>
276</div>
277</body>
278</html>
279