December 30, 2013 - Tagged as: en, c.
It’s been long time since I wrote an interesting post but I still don’t have anything interesting and short enough for me to explain in a blog post. Anyway, here’s a fun C compile time assertion trick that I found in libSDL 2 codebase:
In C we have
typedef which can be used for defining type synonyms. This code:
typedef int test;
test as type synonym for int, and then you can replace
ints in variable declarations with
Interestingly, you can also use illegal type names for typedefs, like this:
typedef int foo;
This is funny, because you can’t use
foo as type of a variable, so I don’t understand why this syntax is allowed. I think the reason is that a
typedef is just like declaration and shares same syntax with it, so this is allowed. Still, this declaration looks pretty useless to me.
Anyway, apparently there are some other interesting uses of
typedefs. This code:
typedef int foo[-1];
test.c:13:17: error: 'foo' declared as an array with a negative size typedef int foo[-1]; ^~
Furthermore, there are some expression-like C syntax that are actually evaluated at compile time1. For example:
typedef int foo[3-4];
3-4 looks like an expression, but it’s actually evaluated at compile-time and thus this code fails with same error as above.
Using this two tricks, we can have some kind of compile-time assertions, like libSDL people use:
#define COMPILE_TIME_ASSERT(name, x) \ typedef int dummy_ ## name[(x) * 2 - 1] typedef uint16_t Uint16; sizeof(Uint16) == 2);COMPILE_TIME_ASSERT(uint16,
This code checks in compile time if
Uint16 really represents 2 bytes in memory and it fails to compile if it doesn’t. Interesting part here is that
(x) * 2 - 1 expression evaluated at compile-time.2