C++0x static assert - Datalogisk Institut

C++0x static assert
Asger Bruun
Generisk programmering og biblioteksudvikling.
Datalogisk Institut, Københavns Universitet.
9. maj 2008
The problem
The standard ways in C++ to test for software assertions
I
before compile: use the #error preprocessor directive
I
compile time: missing!
I
after compile: use the runtime assert
A compile time check makes it possible for a template library to
detect a wrong template instantiation and tell the user what is
wrong. Without it, then the library can hope or make sure for an
internal compilation failure, that will eventually prevent the user in
going runtime.
Work arounds
The problem can be solved with some less beautiful compiler hacks
I
Boost: BOOST STATIC ASSERT(expr)
I
Loki: LOKI STATIC CHECK(expr,err-mesg-type)
I
CPH STL: static assert(expr,err-mesg-type)
Inadequacies: a) name space polution because of new types is the
only way to communicate error messages to the user, b) worse,
Boost basically tell the user no more than something went wrong
in the library and that the user should consult this library source 1 .
1
is the same as removing the explanation, not matter how internal it was
The proposal
The proposal is a new keyword in namespace scope, block scope,
and class member declaration lists,
static assert-declaration:
static assert ( constant-expression , string-literal ) ;
The proposal eliminates the compiler twisting of present days.
Test
Get most compiler libraries possibly into system in advance
I
MS VS2008: a) install Windows SDK first (to avoid
obstruction of TR1 another day from this known threat).
b) install Visual C++ 2008 Feature Pack which includes all
the implemented parts of TR1.
I
or GCC: the newest update will have all standards included
the implemented parts of C++ TR1.
Use case 1, of proposal
I
BOOST STATIC ASSERT(sizeof(long) >= 8); // 64-bit code
generation is not enabled/supported.
I
LOKI STATIC CHECK(sizeof(long) >= 8,
64 bit code generation not enabled supported);
I
CPHSTL: static assert(sizeof(long) >= 8,
64 bit code generation not enabled supported);
I
C++0x: static assert(sizeof(long) >= 8, 00 64-bit code
generation is not enabled/supported.00 );
2
2
the size of long is 32 bit in MS VC x64 code generation.
Use case 1, compiler error messages
3
error C2027: use of undefined type 0 boost::STATIC ASSERTION FAILURE<x>0
with
[
x=false
]
4 —
error C2079: 0 ERROR 64 bit code generation not enabled supported0 uses undefined
struct 0 Loki::CompileTimeError< formal>0
with
[
formal=0
]
—
error C2440: 0 <function-style-cast>0 : cannot convert from
0 case1::tst::ERROR 64 bit code generation not enabled supported0 to 0 type0
No constructor could take the source type, or constructor overload resolution was
ambiguous
4
3
Boost is the only solution that works properly in namespace scope.
MS VC x86 code generation.
Result
Consequences
I
the new keyword, static assert, is probably useful
I
a new keyword may create collisions with existing code
Is it an ill-timed quick fix for the general limitation that the only
valid template arguments are types and integral constants?
References
The C++ Standards Committee, N1720: Proposal to Add Static
Assertions to the Core Language (Revision 3), 2004-10-20.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2521.pdf
The C++ Standards Committee, N2521: Working Draft, Standard for
Programming Language C++, 2008-02-04.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2521.pdf
CPH STL Library, static assert, 2001-.
http://loki-lib.sourceforge.net/index.php?n=Idioms.CompileTimeCheck
Loki Library, LOKI STATIC CHECK, 2001-.
http://loki-lib.sourceforge.net/index.php?n=Idioms.CompileTimeCheck
Boost Library, BOOST STATIC ASSERT, 2000-. http:
//www.boost.org/doc/libs/1_35_0/doc/html/boost_staticassert.html