RSS / Atom

clever c trick

2009-03-14 , ,

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.


Comment [1]

2009-03-19 19:52 , Ross

I have the FFI nearly working and now I\'m nearly certain I\'ve approached it wrong, trying to do the heavy lifting in C. All I need are conversions of a few primitive types and then can do all the definition and manipulation in Scheme. Reading good code like CFFI demonstrates how much easier it might be.

Commenting is closed for this article.