diff --git a/static_assert.htm b/static_assert.htm index adfbb65..6e941de 100644 --- a/static_assert.htm +++ b/static_assert.htm @@ -1,58 +1,40 @@ - - - - - -static assertions - - - - -

Header -<boost/static_assert.hpp>

- -

The header <boost/static_assert.hpp> supplies a single -macro BOOST_STATIC_ASSERT(x), which generates a compile time -error message if the integral-constant-expression -x is not true. In other words it is the compile time -equivalent of the assert macro; this is sometimes known as a -"compile-time-assertion", but will be called a "static -assertion" throughout these docs. Note that if the condition -is true, then the macro will generate neither code nor data - and -the macro can also be used at either namespace, class or function -scope. When used in a template, the static assertion will be -evaluated at the time the template is instantiated; this is -particularly useful for validating template parameters.

- -

One of the aims of BOOST_STATIC_ASSERT is to generate readable -error messages. These immediately tell the user that a library is -being used in a manner that is not supported. While error -messages obviously differ from compiler to compiler, but you -should see something like:

- -
Illegal use of COMPILE_TIME_ASSERTION_FAILURE<false>
- -

Which is intended to at least catch the eye!

- -

You can use BOOST_STATIC_ASSERT at any place where you can -place a declaration, that is at class, function or namespace -scope, this is illustrated by the following examples:

- -

Use at namespace scope.

- -

The macro can be used at namespace scope, if there is some -requirement must always be true; generally this means some -platform specific requirement. Suppose we require that int -be at least a 32-bit integral type, and that wchar_t be an -unsigned type. We can verify this at compile time as follows:

- -
#include <climits>
+   
+      static assertions
+      
+      
+      
+   
+   
+      

Header <boost/static_assert.hpp>

+

The header <boost/static_assert.hpp> supplies a single macro + BOOST_STATIC_ASSERT(x), which generates a compile time error message if the + integral-constant-expression x is not true. In other words it is + the compile time equivalent of the assert macro; this is sometimes known as a + "compile-time-assertion", but will be called a "static assertion" throughout + these docs. Note that if the condition is true, then the macro will generate + neither code nor data - and the macro can also be used at either namespace, + class or function scope. When used in a template, the static assertion will be + evaluated at the time the template is instantiated; this is particularly useful + for validating template parameters. +

+

One of the aims of BOOST_STATIC_ASSERT is to generate readable error messages. + These immediately tell the user that a library is being used in a manner that + is not supported. While error messages obviously differ from compiler to + compiler, but you should see something like: +

+
Illegal use of STATIC_ASSERTION_FAILURE<false>
+

Which is intended to at least catch the eye!

+

You can use BOOST_STATIC_ASSERT at any place where you can place a declaration, + that is at class, function or + namespace scope, this is illustrated by the following examples:

+

Use at namespace scope.

+

The macro can be used at namespace scope, if there is some requirement must + always be true; generally this means some platform specific requirement. + Suppose we require that int be at least a 32-bit integral type, and that + wchar_t be an unsigned type. We can verify this at compile time as + follows:

+
#include <climits>
 #include <cwchar>
 #include <boost/static_assert.hpp>
 
@@ -63,40 +45,31 @@ BOOST_STATIC_ASSERT(WCHAR_MIN >= 0);
 
 } // namespace my_conditions
 
- -

The use of the namespace my_conditions here requires -some comment. The macro BOOST_STATIC_ASSERT works by generating -an typedef declaration, and since the typedef -must have a name, the macro generates one automatically by -mangling a stub name with the value of __LINE__. When -BOOST_STATIC_ASSERT is used at either class or function scope -then each use of BOOST_STATIC_ASSERT is guaranteed to produce a -name unique to that scope (provided you only use the macro once -on each line). However when used in a header at namespace scope, -that namespace can be continued over multiple headers, each of -which may have their own static assertions, and on the "same" -lines, thereby generating duplicate declarations. In theory the -compiler should silently ignore duplicate typedef declarations, -however many do not do so (and even if they do they are entitled -to emit warnings in such cases). To avoid potential problems, if -you use BOOST_STATIC_ASSERT in a header and at namespace scope, -then enclose them in a namespace unique to that header.

- -

Use at function scope

- -

The macro is typically used at function scope inside template -functions, when the template arguments need checking. Imagine -that we have an iterator-based algorithm that requires random -access iterators. If the algorithm is instantiated with iterators -that do not meet our requirements then an error will be generated -eventually, but this may be nested deep inside several templates, -making it hard for the user to determine what went wrong. One -option is to add a static assertion at the top level of the -template, in that case if the condition is not met, then an error -will be generated in a way that makes it reasonably obvious to -the user that the template is being misused.

- -
#include <iterator>
+      

The use of the namespace my_conditions here requires some comment. The + macro BOOST_STATIC_ASSERT works by generating an typedef declaration, + and since the typedef must have a name, the macro generates one automatically + by mangling a stub name with the value of __LINE__. When BOOST_STATIC_ASSERT is + used at either class or function scope then each use of BOOST_STATIC_ASSERT is + guaranteed to produce a name unique to that scope (provided you only use the + macro once on each line). However when used in a header at namespace scope, + that namespace can be continued over multiple headers, each of which may have + their own static assertions, and on the "same" lines, thereby generating + duplicate declarations. In theory the compiler should silently ignore duplicate + typedef declarations, however many do not do so (and even if they do they are + entitled to emit warnings in such cases). To avoid potential problems, if you + use BOOST_STATIC_ASSERT in a header and at namespace scope, then enclose them + in a namespace unique to that header.

+

Use at function scope

+

The macro is typically used at function scope inside template functions, when + the template arguments need checking. Imagine that we have an iterator-based + algorithm that requires random access iterators. If the algorithm is + instantiated with iterators that do not meet our requirements then an error + will be generated eventually, but this may be nested deep inside several + templates, making it hard for the user to determine what went wrong. One option + is to add a static assertion at the top level of the template, in that case if + the condition is not met, then an error will be generated in a way that makes + it reasonably obvious to the user that the template is being misused.

+
#include <iterator>
 #include <boost/static_assert.hpp>
 #include <boost/type_traits.hpp>
 
@@ -111,24 +84,19 @@ RandomAccessIterator foo(RandomAccessIterator from, RandomAccessIterator to)
    // detail goes here...
    return from;
 }
- -

A couple of footnotes are in order here: the extra set of -parenthesis around the assert, is to prevent the comma inside the -is_convertible template being interpreted by the preprocessor as -a macro argument separator; the target type for is_convertible is -a reference type, as some compilers have problems using -is_convertible when the conversion is via a user defined -constructor (in any case there is no guarantee that the iterator -tag classes are copy-constructible).

- -

Use at class scope

- -

The macro is typically used inside classes that are templates. -Suppose we have a template-class that requires an unsigned -integral type with at least 16-bits of precision as a template -argument, we can achieve this using something like this:

- -
#include <climits>
+      

A couple of footnotes are in order here: the extra set of parenthesis around + the assert, is to prevent the comma inside the is_convertible template being + interpreted by the preprocessor as a macro argument separator; the target type + for is_convertible is a reference type, as some compilers have problems using + is_convertible when the conversion is via a user defined constructor (in any + case there is no guarantee that the iterator tag classes are + copy-constructible).

+

Use at class scope

+

The macro is typically used inside classes that are templates. Suppose we have + a template-class that requires an unsigned integral type with at least 16-bits + of precision as a template argument, we can achieve this using something like + this:

+
#include <climits>
 #include <boost/static_assert.hpp>
 
 template <class UnsignedInt>
@@ -143,137 +111,112 @@ public:
    /* details here */
 };
 
- -

How it works

- -

BOOST_STATIC_ASSERT works as follows. There is class -STATIC_ASSERTION_FAILURE which is defined as:

- -
namespace boost{
+      

How it works

+

BOOST_STATIC_ASSERT works as follows. There is class STATIC_ASSERTION_FAILURE + which is defined as:

+
namespace boost{
 
 template <bool> struct STATIC_ASSERTION_FAILURE;
 
 template <> struct STATIC_ASSERTION_FAILURE<true>{};
 
 }
- -

The key feature is that the error message triggered by the -undefined expression sizeof(STATIC_ASSERTION_FAILURE<0>), -tends to be consistent across a wide variety of compilers. The -rest of the machinery of BOOST_STATIC_ASSERT is just a way to -feed the sizeof expression into a typedef. The use of a macro -here is somewhat ugly; however boost members have spent -considerable effort trying to invent a static assert that avoided -macros, all to no avail. The general conclusion was that the good -of a static assert working at namespace, function, and class -scope outweighed the ugliness of a macro.

- -

Test Programs

- -

The following test programs are provided with this library:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Test ProgramExpected to CompileDescription
static_assert_test.cppYesIllustrates usage, and should always - compile, really just tests compiler compatibility.
static_assert_example_1.cppPlatform dependent.Namespace scope test program, may compile - depending upon the platform.
static_assert_example_2.cppYesFunction scope test program.
static_assert_example_3.cppYesClass scope test program.
static_assert_test_fail_1.cppNoIllustrates failure at namespace scope.
static_assert_test_fail_2.cppNoIllustrates failure at non-template - function scope.
static_assert_test_fail_3.cppNoIllustrates failure at non-template class - scope.
static_assert_test_fail_4.cppNoIllustrates failure at non-template class - scope.
static_assert_test_fail_5.cppNoIllustrates failure at template class - scope.
static_assert_test_fail_6.cppNoIllustrates failure at template class - member function scope.
static_assert_test_fail_7.cppNoIllustrates failure of class scope - example.
static_assert_test_fail_8.cppNoIllustrates failure of function scope example.
static_assert_test_fail_9.cppNoIllustrates failure of function scope example (part 2).
- -
- -

Revised 27th Nov 2000

- -

Documentation © Copyright John Maddock 2000. Permission to -copy, use, modify, sell and distribute this document is granted -provided this copyright notice appears in all copies. This -document is provided "as is" without express or implied -warranty, and with no claim as to its suitability for any purpose.

- -

Based on contributions by Steve Cleary and John Maddock.

- -

Maintained by John -Maddock, the latest version of this file can be found at www.boost.org, and the boost -discussion list at www.yahoogroups.com/list/boost. -

- -

 

- -

 

- +

The key feature is that the error message triggered by the undefined expression + sizeof(STATIC_ASSERTION_FAILURE<0>), tends to be consistent across a wide + variety of compilers. The rest of the machinery of BOOST_STATIC_ASSERT is just + a way to feed the sizeof expression into a typedef. The use of a macro here is + somewhat ugly; however boost members have spent considerable effort trying to + invent a static assert that avoided macros, all to no avail. The general + conclusion was that the good of a static assert working at namespace, function, + and class scope outweighed the ugliness of a macro.

+

Test Programs

+

The following test programs are provided with this library:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Test ProgramExpected to CompileDescription
static_assert_test.cppYesIllustrates usage, and should always compile, really just tests + compiler compatibility.
static_assert_example_1.cppPlatform dependent.Namespace scope test program, may compile depending upon the + platform.
static_assert_example_2.cppYesFunction scope test program.
static_assert_example_3.cppYesClass scope test program.
static_assert_test_fail_1.cppNoIllustrates failure at namespace scope.
static_assert_test_fail_2.cppNoIllustrates failure at non-template function scope.
static_assert_test_fail_3.cppNoIllustrates failure at non-template class scope.
static_assert_test_fail_4.cppNoIllustrates failure at non-template class scope.
static_assert_test_fail_5.cppNoIllustrates failure at template class scope.
static_assert_test_fail_6.cppNoIllustrates failure at template class member function scope.
static_assert_test_fail_7.cppNoIllustrates failure of class scope example.
static_assert_test_fail_8.cppNoIllustrates failure of function scope example.
static_assert_test_fail_9.cppNoIllustrates failure of function scope example (part 2).
+
+

Revised 27th Nov 2000

+

Documentation © Copyright John Maddock 2000. Permission to copy, use, modify, + sell and distribute this document is granted provided this copyright notice + appears in all copies. This document is provided "as is" without express or + implied warranty, and with no claim as to its suitability for any purpose.

+

Based on contributions by Steve Cleary and John Maddock.

+

Maintained by John Maddock, the + latest version of this file can be found at www.boost.org, + and the boost discussion list at www.yahoogroups.com/list/boost. +

+

 

+

 

+