In another post I found the following construct:
#define STATIC_ASSERT(condition) \
do \
char foo[condition] = {0}; \
while ( false );
First, I had to do a search to see whether "static" meant "compile-time" here (that poor keyword static, it's got too many overloaded meanings in C and C++). I'm think fairly confident that it means the compile would break if the condition were false, which is the desired outcome for what I have titled here as "Compile Time Assertions".
Anyways, I did a little digging to see how I had done something similar in some fairly recent code. The version I found, and an example of what this does or is intended to do, is like in the following:
#include <stdio.h>
#define COMPILE_TIME_ASSERT(cond, msg) \
typedef unsigned char msg[(cond) ? 1 : 0]
#define NELEM(x) (sizeof(x)/sizeof(*x))
const char *const Table[] =
{
"one", "two", "three", "four", "five", "six",
"seven", "eight", "nine", "ten", "eleven",
"twelve", "thirteen", "fourteen", "fifteen",
#if 0
"sixteen", "seventeen", "eighteen", "nineteen",
#endif
};
COMPILE_TIME_ASSERT(NELEM(Table) < 16, Table_too_big);
int main()
{
size_t i;
for ( i = 0; i < NELEM(Table); ++i )
{
printf("Table[%d] = \"%s\"\n", (int)i, Table[i]);
}
return 0;
}
In the case where more elements are added to the table (changing #if 0
to #if 1
), I get the following error:
main.c:18: warning: ISO C forbids zero-size array `Table_too_big'
I was just curious what other variations of this people might have encountered, and whatever reasons they have for preferring one way to another.
I guess I'd chosen to have a second parameter as a "message" which would be an identifier whose name would hopefully be descriptive of the issue. And apparently the typedef is to prevent even a single extra byte of data to be defined in the build of either a version with this assert present or not. I think this same thing is being done by Narue's use of local scope in the do-while.
Anyways, what other variations might people have used?