You can use any expression that needs a constant integral expression and which will then be optimized.
#define NPOT(X) \ (1 \ ? complex_algorithm(X) \ : sizeof(struct { int needs_constant[1 ? 1 : (X)]; }) \ )
ultimately, you must point the result of sizeof to the appropriate integer type, so the return expression is of the type you expect.
I use unlabeled struct here for
- are of type, so in fact temporary is not created
- have a unique type so that the expression can be repeated anywhere in the code without causing conflicts
- starts using VLA, which is not allowed inside a
struct with C99:
An element of a structure or union may have any type of object other than a modified type.
I use triple ?: With 1 as an expression for selection, to ensure that : always evaluated for its type, but never evaluated as an expression.
Edit: It seems that gcc accepts the VLA inside the struct as an extension and doesn't even warn about it, even when I explicitly say -std=c99 . This is a really bad idea about them.
For such a strange compiler :) you can use sizeof((int[X]){ 0 }) instead. This is "forbidden" as stated above, but additionally even gcc complains about it.
source share