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");
}

Leave a CommentTrackback