I use a macro to provide a static assert mechanism similar to that provided by C11:
#define STATIC_ASSERT(condition, message) \ typedef char \ CAT( \ CAT( \ CAT( \ CAT( \ CAT(STATIC_ASSERT_FAILED___, \ message), \ ___LINE_), \ __LINE__), \ ___UID_), \ __COUNTER__) \ [2*(!!(condition))-1] __attribute__ ((__unused__))
#define CONCATENATE(a, b) CONCATENATE_(a, b) #define CONCATENATE_(a, b) a ## b #define CAT CONCATENATE
This works well, and can be used both at file scope and function scope.
I ran into an issue when the condition involves non-integer constants:
#define T0 -23.6 #define T1 2.1 STATIC_ASSERT((T1 > T0), T1_must_be_larger_than_T0);
This generates a warning (error with -Werror):
error: variably modified 'STATIC_ASSERT_FAILED___T1_must_be_larger_than_T0___LINE_217___UID_0' at file scope [-Werror] STATIC_ASSERT(1.0, T1_must_be_larger_than_T0); ^
The issue seems related to the fact that the arguments in the conditional expression used to compute the size of the array are floating point numbers. (Note that the fact the arguments are floats does not result in a float for the array size, since the result of the conditional is itself an integer).
So the question I have is: 'Why'?
They are literals. They can be evaluated at compile time. The conditional can be evaluated at compile time. Why is the compiler concluding that the array size is 'variably modified'?
Is this related to a compiler's inability to reduce something like this:
foo = (bar * 2.0) / 5.0;
... into this:
foo = bar * 0.4;
... due to the possibility (though absent in that specific example) of rounding errors?
More importantly, is there an alternative? Other than scaling T0 and T1 into integers?