Sometimes, it is desirable to perform computations already at compile-time — either for efficiency or to avoid redundancy. Alas, what a compiler can compute at compile-time is rather limited — mostly just a combination of unary and binary operators. What if you need to do something more complex?

For the sake of illustration, I chose computing the (floored) log2 of an integer as an example, but the techniques presented below can be easily adapted to other use cases:

But since template metaprogramming was not deliberately built into C++ but rather discovered by accident, template metaprogramming code is far from pleasant to look at. If you are lucky and your compiler supports C++11 (or rather C++11’s constexpr feature), you have a better option:

1

2

3

4

5

6

7

8

constexpr intstatic_log2_constexpr_impl(intvalue,intshift){

returnshift==-1?-1:

value&(1<<shift)?shift:

static_log2_constexpr_impl(value,shift-1);

}

#define STATIC_LOG2(value)\

(static_log2_constexpr_impl(value,sizeof(int)*CHAR_BIT-1))

It’s still recursive, but at least this solution is using real functions and not structs to achive its goal — much easier on the eyes!

But what if you code at the other end of the spectrum? What if you are limited to plain C?

Many years ago, I discovered the following technique that has proven useful in quite a few situations; it is used like this:

1

2

3

#define STATIC_LOG2_ARG 89

#include static_log2.h

charmyarray[STATIC_LOG2_VALUE];// sizeof(myarray) == 6

The “argument” is passed via a symbolic constant (STATIC_LOG2_ARG), the computation is done by “calling the function” (by including static_log2.h) and the “return value” is stored in another symbolic constant (STATIC_LOG2_VALUE).