I have a compile time counter that I have used for many years, inspired by these answers . It works in C ++ 03/11, and as far as I checked it is relatively good on the main compilers:
namespace meta { template<unsigned int n> struct Count { char data[n]; }; template<int n> struct ICount : public ICount<n-1> {}; template<> struct ICount<0> {}; #define MAX_COUNT 64 #define MAKE_COUNTER( _tag_ ) \ static ::meta::Count<1> _counter ## _tag_ (::meta::ICount<1>) #define GET_COUNT( _tag_ ) \ (sizeof(_counter ## _tag_ (::meta::ICount<MAX_COUNT + 1>())) - 1) #define INC_COUNT( _tag_ ) \ static ::meta::Count<GET_COUNT(_tag_) + 2> _counter ## _tag_ (::meta::ICount<2 + GET_COUNT(_tag_)>) }
The following test compiles and works fine (expected result 0 1 2 3 ):
struct Test { MAKE_COUNTER( uu ); static const unsigned int a = GET_COUNT( uu ); INC_COUNT( uu ); static const unsigned int b = GET_COUNT( uu ); INC_COUNT( uu ); static const unsigned int c = GET_COUNT( uu ); INC_COUNT( uu ); static const unsigned int d = GET_COUNT( uu ); }; template<typename T> void test() { std::cout << T::a << " " << T::b << " " << T::c << " " << T::d << "\n"; } int main() { test<Test>(); }
However, I found that I see very strange behavior happening with clang and gcc. If you change Test as a template structure, take an int, for example ( template<int> struct Test and test<Test<42> >() in main ), clang and gcc cannot both compile , complaining that I override the counter function (in while msvc compiles it without problems). For some reason, the compiler cannot calculate sizeof in the template class.
clang find the error on the third INC_COUNT , and gcc find it on the second.
I manually extended this macro and:
for clang, he gives
static ::meta::Count<GET_COUNT(uu)+2> _counteruu(::meta::ICount<(sizeof(_counteruu(::meta::ICount<65>())) - 1)+2>); // ^ ^
removing underlined parentheses solves the problem.
for gcc: moving +2 before sizeof is the only workaround
It is sad to note that these workarounds do not seem to work when included in macros. He, as a compiler, just forgets how to calculate the sizeof result after some time ...
Why is this happening? Am I doing something wrong, or are these just compiler errors (since clang and gcc don't even report the same line)?
Note. I know there is a gcc error about this counter . The question is not this error.