Mon Jun 6 11:30:01 CEST 2011

Compile time assert

I need a compile-time assert macro that can go into proprietary code,
so can't use the one in Linux.

Good news: I did not look at any code yet, so can I reinvent it?  The
trick alledgedly is to use the macro arguments to construct data of
negative size.

So let's analyze this:  CT_ASSERT(x)

  - If the argument of the assert macro is zero, a compilation error
    is triggered.

  - To trigger a compilation error, construct a data structure with
    negative size.

  - A name is necessary for the data structure, so let's use a name
    generation macro (GENSYM[1]).

It turns out to be quite straightforward: using result values of
boolean expressions (after a comparison of the input to 0), a simple
negation can be used to map the failed assert to a negative array

#define CTASSERT(x) static const char GENSYM(ctassert_)[-((x)==0)];

EDIT: There is even a more elegant way.  Instead of using a code
construct that has a run-time run-time remnant as a symbol part of the
binary if it's not optimized out, it's possible to use just a
completely ephemeral construct: i.e. a type.

#define CTASSERT(x) struct GENSYM(ctassert_) {char a[-((x)==0)]; }

EDIT: It's also possible to avoid size 0 arrays and use size -1 for
false and size +1 for true:

#define CT_ASSERT(x) struct GENSYM(_ctassert_){ char a[1 - 2*((x)==0)]; }

[1] entry://20100825-142132