Answer: The Struct Offset Interview Question

 

Ok, so you have your answer? First, a few questions to show you how the interview usually went:

  1. Did you just write down a number like 12?
  2. Did you use sizeof?
  3. What if the size of an integer is 8-bytes on one architecture and 4 bytes on another?
  4. What about structure packing? There’s probably a weird unused byte after the character array. How did you account for that?
  5. What if someone adds, removes, or reorders your class variables without telling you?
  6. Does your solution involve allocating or otherwise declaring an instance of a foo_t?
  7. Does your answer compile down to an O(1) operation?

The real answer is robust in the face of data changes, platform differences, and structure packing.

struct foo_t
{
    int a;
    float b;
    char c[3];
    void * zPtr;
};

The answer is:

<offset> = (int)&(((foo_t*)0)->zPtr)

We don’t need any instances of the type or even a whole function, and it reduces to a single integer constant at compile time. This code can be put inside of a macro, and even made more general so that it can get the offset from any data member of any structure:

#define MyOffset(TYPE, MEMBER)  (int)&(((TYPE*)0)->MEMBER)

There are some variations on this code using simple subtraction as well as some formalizations using the ptr_diff type, but that’s getting into minutiae that starts to get tangential to the problem. I was interested in seeing if the candidate knew that structures and platforms have nuances that you won’t always know about at code-time. Next, I wanted to see if they knew how structures were addressed internally and that the compiler always knows the magic value they’re after; if only it could be coaxed out. Finally, I wanted to see if they knew enough about machine code and addressing modes to know that they weren’t actually dereferencing NULL in there, and it won’t crash.

But what about offsetof?

Ahh, I can already hear the more experienced engineers out there decrying my complete ignorance of the offsetof macro. No, I know it’s there, and if a candidate ever brought that fact up, I would just ask them to implement it – strangely, a few people knew the answer off the top of their heads, but no one has ever mentioned offsetof.

  2 Responses to “Answer: The Struct Offset Interview Question”

  1. I assume by “portable” you are referring to the more common platform differences, like sizes, alignment, etc.. I just feel obligated to point out that the implementation of the offsetof macro is notorious for being non-portable, so using offsetof is the only truly portable way to handle this in C.

    • Hi Brian.
      Essentially, yes. However, I don’t know about offsetof being “notoriously” non-portable. There’s a problem in some versions of gcc with using 0 as the pointer base, so some engines like Unreal (see STRUCT_OFFSET) use a 1 and then simply subtract 1 from the result for PS3. Similarly, Havok (see HK_OFFSET_OF) uses 16-16 for all platforms except a few gcc variants which are treated as special cases. Really, I’ve only seen the problems arise on gcc.

      That’s not really the point of the exercise though. No candidate has ever brought up these little nuances, but I’d have been impressed if they had. All the more fodder to dig into in a technical interview. 🙂

Leave a Reply to Brian Ehlert Cancel reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)