Out of Hanwell

November 16, 2005

Compile-Time Assertions

Filed under: Uncategorized — Matthias Miller @ 4:00 pm

The last edition of C/C++ Users Journal (December 2005) had an article about compile-time assertions. The article proposed using templates like this:

template <bool> class OnlyTrue;
template <> class OnlyTrue<true> {};

#define CTA(X) sizeof(OnlyTrue<(bool)(X)>)

If the expression is true, the sizeof expression will be optimized away by the compiler. If the expression is false, the compiler will give an error because OnlyTrue<false> is not defined. This technique, like the one used by Boost.StaticAssert, requires a class, function, or namespace scope. However, a small tweak allows compile-time assertions anywhere:

template <bool> class OnlyTrue;
template <> class OnlyTrue<true>
{ enum CompileTimeAssertion {}; };

#define CTA(X) \
(OnlyTrue<(bool)(X)>::CompileTimeAssertion)

Like the first assertion, the reference to the enum type will be optimized away if the expression is true and the compiler will give an error if the expression is false. But instead of referencing the size of the template class, this assertion merely references an enum type of the template class, which the compiler allows at the global scope.

The advantage may not be great, but it does make global compile-time assertions just a little easier.

Update: I really goofed here. (Thanks for pointing it out, tv.) Since I wrote this post, I came across the compile-time assertions in SpiderMonkey, which look like this:

#define JS_STATIC_ASSERT(condition)                                           \
JS_STATIC_ASSERT_IMPL(condition, __LINE__)

#define JS_STATIC_ASSERT_IMPL(condition, line)                                \
JS_STATIC_ASSERT_IMPL2(condition, line)

#define JS_STATIC_ASSERT_IMPL2(condition, line)                               \
typedef int js_static_assert_line_##line[(condition) ? 1 : -1]

Same advantages that I mentioned, only it works.

2 Comments »

  1. Which compiler accepts this code? I tried it with gcc 3.4.4 but it doesn’t work at global scope.

    Comment by tv [Visitor] — March 18, 2006 @ 12:31 am

  2. I’m sorry, I goofed. (I tested it in Visual C++, but now I’m questioning what I tested.) I’ll update the post with more accurate information.

    Comment by Matthias Miller [Member] — March 18, 2006 @ 7:14 am


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.