A few fun things you can do with C structures: 1. Bitfields
struct { uint32_t year : 7, month : 4, day : 5, : 5, hour : 5, min : 6; } compact_date;Notes: 1. Turns out that C99 defines fixes-size integer types: no more need to define them yourself. 2. The order in which bits are placed into a bitfield (MSB or LSB first) is not standardised - which is ok if you're only on a single platform, but may get messy otherwise. 3. To leave reserved blank spaces, just leave them blank. 4. If you need fewer bits, just use fewer. This structure can store a date (up to 127 years) using only 4 bytes (as opposed to the naive implementation which would require 5 or more). Not a massive win, but convenient when alignment is a concern. 2. Unions
union { uint16_t isDate : 1, month : 4, day : 5; uint16_t : 1, hour : 5, min : 6; } datetime;This little beauty allows overlapping bitfield definitions: depending on the value of isDate, you can access either month/day or hour:min inside the same compact storage area. 3. Head and trailer structures
struct { uint16_t type; uint16_t len; uint8_t data[1]; } tlv;This is a fairly common construct but still rather useful. Because C doesn't check array bounds, you can readily access additional data[] elements - the only trick becomes handling sizeof() operations cleanly. To get the size of the header (only):
&((tlv*)0)->data)To get the size of the complete structure:
sizeof(tlv) + sizeof(tlv.data[0]) * (data_count - 1)4. And finally, just for fun:
#define STDIO "stdio.h" #define STRING#include STDIO #include STRING int main (int argc, char** argv) { printf("Don't let me catch you doing this!\n"); }