Summary Page 


(n3090.pdf is the current working draft of C++0x standard, it is available at

What we have before C++0x

It is a common task to output meaningful error message from source code based on compile-time conditions. For example, you may want to ensure that the size of your core structure has not been changed by accident.

In C++03, this is achieved by using invalid expressions (like "int array[expr ? 1 : 0];"). However, different compilers have different handling of invalid expressions. It is quite difficult to write portable code to ensure the compilation to fail.

boost has provided “BOOST_STATIC_ASSERT” which is portable, but the error message is far from user-friendly.

What we have now in C++0x

The standard committee adds a new declaration in C++0x: static assert declaration (n3090.pdf, 7/4).

The syntax is:



static_assert ( constant-expression , string-literal ) ;


Given a constant expression which can be converted to false, the compiler will generate an error message which contains the string specified in the declaration


1.       static_assert can be used to validate the value of compile-time constant like structure size.

For example:


#define VALIDATE_TYPE_SIZE(TYPENAME, EXPECTEDSIZE) static_assert(sizeof(TYPENAME) == EXPECTEDSIZE, "The size of "#TYPENAME" is incorrect")


2.       Another usage of static_assert is to validate template argument. This can be an alternative way to achieve what "concept" provides.

(BTW, because static_assert is a declaration, it can be used in both function and class)


In function:


template<typename T>

T GCD(T a, T b)


    static_assert(std::is_integral<T>::value, "T should be an integral type");

    // Calculate GCD


int main()


    GCD(2, 1);

    GCD("hello", "world");



In class:


template<typename T>

struct Complex


    static_assert(std::is_arithmetic<T>::value, "T should be a arithmetic type");



Complex<int> a;

Complex<int *> b;

Known issues / limitations

1.       If the string literal contains characters that are not in the basic source character set (n3090.pdf, 2.3/1), they may not appear in the error message.

That means you’d better not to use non-ASCII characters in the literal. For example, the following code snippet will show no message in VC2010:


static_assert(false, "范翔"); // my Chinese name


2.       The error message of static_assert is fixed. If you want to output additional information, template can help.

For example,


template<size_t ActualSize, size_t ExpectedSize>

struct CheckTypeSize;

template<size_t Size>

struct CheckTypeSize<Size, Size> {};


CheckTypeSize<sizeof(int), 4> check;

What is special in VC2010

In VC2010, static_assert is also supported in C source.

Wide string literal is not supported. You’ll get "error C2002: invalid wide-character constant". As far as non-ASCII characters will not be displayed, this limitation is reasonable.

Known bugs in VC2010

There aren’t too many bugs related to static_assert.

Here is one that I know:


enum {e};


template<typename T>

struct A





struct A<int>


    static const int a = e;



template<typename T>

struct B : A<T>


    static_assert(A<T>::a == e, "fail");



int main()


    B<int> b;



When you compile the code, you’ll get "error C2677: binary '==' : no global operator found which takes type '' (or there is no acceptable conversion) "


There are several conditions to repro this bug.

First, B should derive from A<T>.

Second, the primary template of A should not contain the definition of a.

Third, 'e' should be an enum member.


The workaround is fairly simple. One possible way is to use "(int)e" in the constant expression.