Closures In Straight C

I’ve read a lot lately about closures. I’ve read articles where people wonder what they are, others where someone is lamenting the fact that they only recently discovered them. I too only recently discovered the joy of closures. I’ve been writing a lot of javascript recently and I love the way writing anonymous callback functions works. But it turns out I have already been using closures for a long, long time.

A friend and I were discussing C (our language of choice for embedded programming) and the things we like about it and somehow the subject of closures came up. I started thinking about what it would take to implement closures in C. Would you do it in the compiler as a language extension or just build them up by hand using in C itself in a cross-platform way?

And then it struck me: I’ve already been using, in straight, boring old C, the concept of closures. And I’ve been using them practically forever. I would say almost since I first learned C on my Macintosh back in high school.

The original Mac API (which still mostly lives on in Mac OS X’s “carbon” API) has an element in almost every major structure called “refCon”. The Apple documentation sorted of glazed over them (or maybe I glazed over when reading about them) and so I puzzled over these for a long time until I realized that they were pieces of memory that the Mac system would never look at or change. They are for the application writer to use as they see fit.

Apple also uses them when you register a function that the system will call at some later time. Here’s an example I grabbed from the current carbon window manager documentation:

OSStatus InstallWindowContentPaintProc(WindowRef window,
                                       WindowPaintUPP paintProc,
                                       WindowPaintProcOptions options,
                                       void *refCon); 

What might you use one for? Well typically you’d create a structure with whatever local data needs to be associated with the call back function and put the pointer to that structure into the refCon. The callback function (since you’re writing it) knows to cast the refCon to the appropriate structure pointer so that it can get access to the fields of the structure.

This is by no means some great thing that Apple discovered. Almost every C API that has callbacks uses the same sort of concept. Here’s a function prototype from glib (one of the gnome base libraries):

guint g_io_add_watch(GIOChannel *channel,
                     GIOCondition condition,
                     GIOFunc func,
                     gpointer user_data);

Here “user_data” serves the same purpose as “refCon” did in the first example. The function you pass in “func” will get “user_data” passed to it (unmolested) by glib.

I’ve used this in almost every API I’ve ever written that has callbacks. Here’s another example from an embedded project I’m working on:

void add_timer(int (*timer)(), void *cookie, int timeout_ms); 

I always name my refCons “cookie”, for some reason. Arguably “user_data” is a more descriptive name, but I sort of like the arbitrariness of “cookie”. Or maybe it just makes me think of cookies… MMMM… Cooookies…

So when I learned javascript and started coding Green Felt I wrote a little XMLHttp() wrapper to make the interface nicer (like every other ajax developer on the planet) and I put in a cookie. Later I realized that everything I was passing in the cookie was a local variable and therefore was already saved in the closure. So passing it explicitly through my ajax function was pointless.

It turns out that all those “cookie”, “user_data”, and “refCon” pointers that I had been using since I first learned C transform the user supplied function pointers into “closures”. They do it explicitly and without any syntactic sugar, but they are 100% the same conceptually. In effect you allocate some memory, put references to some of your local variables into the structure and then pass the structure along with the function pointer to be called back later. The callback can use the structure all it wants which ends up being equivalent to a real closure having direct access to those same local variables.

So… Closures aren’t anything new. C has had closures forever. Yes, you have to manually allocate and deallocate the memory for your variables without syntactic sugar… But, hey, that’s C!

Hardware friendly C structures

What I really want is a language that has really good structures. That is, they can represent hardware/fixed layouts effectively.

Say I were to enhance C (instead of designing a whole new language). I want something like this:

struct FATBoot {
    uint8_t BS_jmpBoot[3];
    char BS_OEMName[8];
    little uint16_t BPB_BytsPerSec;
    uint8_t BPB_SecPerClus;
    little uint16_t BPB_RsvdSecCnt;
    uint8_t BPB_NumFATs;
    little uint16_t BPB_RootEntCnt;
    little uint16_t BPB_TotSec16;
    uint8_t BPB_Media;
    little uint16_t BPB_FATSz16;
    little uint16_t BPB_SecPerTrk;
    little uint16_t BPB_NumHeads;
    little uint32_t BPB_HiddSec;
    little uint32_t BPB_TotSec32;
    union {
        struct { // FAT12 and FAT16 only:
            uint8_t BS_DrvNum;
            uint8_t BS_Reserved1;
            uint8_t BS_BootSig;
            little uint32_t BS_VolID;
            char BS_VolLab[11];
            char BS_FilSysType[8];
        struct { // FAT32 only:
            little uint32_t BPB_FATSz32;
            little uint16_t BPB_ExtFlags;
            little uint16_t BPB_FSVer;
            little uint32_t BPB_RootClus;
            little uint16_t BPB_FSInfo;
            little uint16_t BPB_BkBootSec;
            uint8_t BPB_Reserved[12];
            uint8_t BS32_DrvNum;
            uint8_t BS32_Reserved1;
            uint8_t BS32_BootSig;
            little uint32_t BS32_VolID;
            char BS32_VolLab[11];
            char BS32_FilSysType[8];
        little uint16_t BS_FATMagic;

I picked this structure because I was unable to represent it in my fat C code because of the crazy alignment. The only thing new yet is the “little” and “align” keywords to specify endian, and alignment/offset respectively. You would probably end up using typedefs like “luint16_t” instead of “little uint16_t”. “big”, of course, would also exist. If neither is specified, then you don’t care and therefore should be implementation defined.

Then what I want is this:

    tight FATBoot diskBoot;
    loose FATBoot memBoot;
    pread(fd, &diskBoot, sizeof(diskBoot), 0);
    memBoot = diskBoot;

memboot is the structure using the alignment and endianness of the host processor (the “loose” keyword). diskBoot is the structure packed as specified and using the endian specified. The endian would be enforced so that the memory image of diskBoot would always be correct. Accessing diskBoot.BPB_TotSec32 would evaluate to the EXACT same thing as memBoot.BPB_TotSec32 but memBoot would be quicker since it doesn’t have to reverse (potentially) or read the bytes out and reconstruct the uint16 in some odd way (because of the weird alignment of the structure). This puts a lot of extra burden on structure copies when one is loose and one is tight, so you would expect them to be slow–certainly not memcpy() speeds.

You could also use “strict” and “relaxed” but “loose” and “tight” are both 5 letters. 🙂

Basically, I want the compiler to deal with stupid endianness for me. I also want my structure to not be compiler dependant. I should be able to publish the structure in my spec and it should work on all compilers and architectures. Bit fields, for instance would be specified a certain way and not be “implementation defined”. At lease the tight ones would. Loose means “implementation defined, and fast”. Tight means “standards defined, but possibly slower”.

Last Modified on: Dec 31, 2014 18:59pm