Thursday, March 13, 2008

Making the C Macro 'offsetof' Work with C++

The macro offsetof is a little-known bit of C tucked away in stddef.h. It computes the byte offset of a member from the start of the structure. It is defined in gcc 3.3 as...

#define offsetof(__s_name, __m_name) ((__size_t)((__s_name*)0)->__m_name))

It's clever, efficient, and portable. It is particularly useful in embedded systems, and often legacy systems as well. There is just one problem with using it in C++ , it will be incompatible with any class with a user defined constructor, for then ((class*)0)->member becomes illegal. Interestingly, the construct ((class*)1->member is not (go figure), so the solution is to redefine offsetof after any include of stddef.h as...

#define offsetof(c,m) ((size_t)((c*)1->m)-1)

If the compiler complains about a redefinition, just undef it first.

1 comment:

Nick said...

My instinct is that you should avoid poking around inside a struct. Trust the compiler and use standard methods.
Have you profiled the code and seen that the places where you want to use offset is actually the bottleneck. Not just "inefficient". But the bottleneck for use cases you are concerned about.