Handmade Hero»Forums»Code
4 posts
Compile Time Asserts and OffsetOf
Hi All,

I just watched Day 17.

I thought I might have an elegant solution to the size of Buttons problem.

Turns out I didn't, but I like compile time asserts so I figured this might be of interesting to someone.

The code below throws a compile time assert (or static assert) if the Buttons array is smaller than the anonymous struct. :)

Unfortunately, it does not assert if the opposite is true ( i.e. sizeof(array) > sizeof(struct) ). :(

Not recommending this necessarily as it's not very intuitive code.
If this sort of post isn't appropriate for this forum, let me know and I'll avoid posting weird stuff like this.

Cheers, :)


[code=c]
/*
* Boiler plate compile time assert code
* source: http://stackoverflow.com/question...rt-expressions-at-build-time-in-c
*/
#ifdef __GNUC__
#define STATIC_ASSERT_HELPER(expr, msg) \
(!!sizeof \ (struct { unsigned int STATIC_ASSERTION__##msg: (expr) ? 1 : -1; }))
#define STATIC_ASSERT(expr, msg) \
extern int (*assert_function__(void)) [STATIC_ASSERT_HELPER(expr, msg)]
#else
#define STATIC_ASSERT(expr, msg) \
extern char STATIC_ASSERTION__##msg[1]; \
extern char STATIC_ASSERTION__##msg[(expr)?1:2]
#endif /* #ifdef __GNUC__ */
/* End boiler plate */

/* OffsetOf
* source : http://en.wikipedia.org/wiki/Offsetof
*/
#define offsetof(st, m) ((size_t)(&((st *)0)->m))

/* Count OffsetOf - as above but returns the ArrayCount*/
#define offsetof_count(st, m) ((size_t)(ArrayCount(((st *)0)->m)))

STATIC_ASSERT( // ASSERT
(sizeof(game_controller_input) // ( sizeof game_controller_input
- offsetof(game_controller_input, Buttons)) // MINUS offset of Buttons
/ sizeof(void*) // DIVIDED BY pointer size )
== // EQUALS
offsetof_count(game_controller_input, Buttons), // ArrayCount of Buttons
game_controller_input_buttons_size_mismatch); // Assert with this msg

/* Other examples of usage:
* STATIC_ASSERT(12 == offsetof_count(game_controller_input, Buttons), InvalidCount);
* STATIC_ASSERT(12 == offsetof(game_controller_input, Buttons), InvalidOffset);
* STATIC_ASSERT(0x6C == sizeof(game_controller_input), InvalidSize);
*/
[/code]
Mārtiņš Možeiko
2559 posts / 2 projects
Compile Time Asserts and OffsetOf
I don't think there is need to create your own STATIC_ASSERT macro, because we are compiling C++ code with C++11 capable compiler. So you can simply use static_assert: http://en.cppreference.com/w/cpp/language/static_assert

It will give much cleaner compile error messages.

For offsetof you can simply include <stddef.h> header, it is in there: http://en.cppreference.com/w/cpp/types/offsetof
4 posts
Compile Time Asserts and OffsetOf
Nice!

That's much cleaner.

Thanks :)