#define INIT(N) \
[(N)] = (sizeof((struct {_Static_assert((N) < 42, "too large");char c[N];}){{0}}.c))
... I'm not sure myself how I ended up with that abomination. But hey, it works (for N > 0
) !
// A struct declaration is a valid place to put a static_assert
struct {_Static_assert((N) < 42, "too large"); }
// Then we can place that declaration in a compound literal...
(struct {_Static_assert((N) < 42, "too large"); }){ }
// But we can't just throw it away with `,`: that would yield a non-constant expression.
// So let's add an array of size N to the struct...
(struct {_Static_assert((N) < 42, "too large");char c[N];}){{0}}
// And pry N out again through sizeof!
sizeof((struct {_Static_assert((N) < 42, "too large");char c[N];}){{0}}.c)
0
-friendly version (just adding then subtracting 1
so the array has a positive size):
#define INIT(N) \
[(N)] = (sizeof((struct { \
_Static_assert((N) < 42, "too large"); \
char c[(N) + 1]; \
}){{0}}.c) - 1)