Contents

clever c trick

Contents

I had a few days of vacation visting my folks and started a little hobby hacking in the evenings- the details of which are grist for other, longer posts- but the set up is that I’m working on an FFI (foreign function interface) and have a variety of structs that I want to pass back and forth. I don’t want to handle each struct with unique getter/setters or use hairy if/else or switch/case statements because it’s tedious to write and hard to maintain and I’m not sure where I’m going with this code. I worked out a generic dispatch function with a jump table and having the C preprocessor and compiler build most of it for me. To do that I needed to get the offset of the structure member and its size and came up with this preprocessor macro:

@
#define _off_sz(type,memb) offsetof(type,memb), sizeof(((type *)0)->memb)
@

I’d never seen it before and thought myself quite clever with the cast
zero since I can do this:

   #include <stddef.h>
    #include <stdlib.h>
        ...
    typedef struct tag_vtable_rec {
      pointer  (*fp)();
      int      argc;
      size_t   offset;
      size_t   size;
    } vtable;
        ...
    vtable ffi_foo_vt[] = {
       { some_func,  2, _off_sz(SomeStruct, SomeMember) },
       { other_func, 1, _off_sz(SomeStruct, OtherMember) },
           ...
    };
        ...

It turns out that this technique of casting zero and using `sizeof()` is old and well-known. I have found it argued over in `comp.lang.c` at least as early as 2002 and Nigel Jones wrote a macro almost exactly like mine (and properly casts the `sizeof()` result to `size_t`, which I’ll fix) in 2004 for Embedded Systems Magazine.