{"id":217,"date":"2011-05-21T14:43:38","date_gmt":"2011-05-21T21:43:38","guid":{"rendered":"http:\/\/www.myopictopics.com\/?page_id=217"},"modified":"2012-05-01T13:58:50","modified_gmt":"2012-05-01T20:58:50","slug":"answer-the-struct-offset-interview-question","status":"publish","type":"page","link":"https:\/\/www.myopictopics.com\/?page_id=217","title":{"rendered":"Answer: The Struct Offset Interview Question"},"content":{"rendered":"<p>Ok, so you have your answer? First, a few questions to show you how the interview usually went:<\/p>\n<ol>\n<li>Did you just write down a number like 12?<\/li>\n<li>Did you use <span style=\"font-family: courier;\">sizeof<\/span>?<\/li>\n<li>What if the size of an integer is 8-bytes on one architecture and 4 bytes on another?<\/li>\n<li>What about structure packing? There\u2019s probably a weird\u00a0unused\u00a0byte after the character array. How did you account for that?<\/li>\n<li>What if someone adds, removes, or reorders your class variables without telling you?<\/li>\n<li>Does your solution involve allocating or otherwise declaring an instance of a\u00a0<span style=\"font-family: courier;\">foo_t<\/span>?<\/li>\n<li>Does your answer compile down to an O(1) operation?<\/li>\n<\/ol>\n<p>The real answer is robust in the face of data changes, platform differences, and structure packing.<\/p>\n<pre><code>struct <span style=\"color: #339966;\">foo_t<\/span>\r\n{\r\n    <span style=\"color: #339966;\">int <\/span><span style=\"color: #0000ff;\">a<\/span>;\r\n    <span style=\"color: #339966;\">float <\/span><span style=\"color: #0000ff;\">b<\/span>;\r\n    <span style=\"color: #339966;\">char <\/span><span style=\"color: #0000ff;\">c<\/span>[3];\r\n    <span style=\"color: #339966;\">void <\/span>* <span style=\"color: #0000ff;\">zPtr<\/span>;\r\n};\r\n<\/code><\/pre>\n<p>The answer is:<\/p>\n<pre>&lt;offset&gt; = (<span style=\"color: #339966;\">int<\/span>)&amp;(((<span style=\"color: #339966;\">foo_t<\/span>*)<span style=\"color: #0000ff;\">0<\/span>)-&gt;<span style=\"color: #339966;\">zPtr<\/span>)<\/pre>\n<p>We don\u2019t need any instances of the type or even a whole function, and\u00a0it 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:<\/p>\n<pre>#define <span style=\"color: #339966;\">MyOffset<\/span>(<span style=\"color: #ff0000;\">TYPE<\/span>, <span style=\"color: #ff0000;\">MEMBER<\/span>) \ufeff\ufeff (<span style=\"color: #339966;\">int<\/span>)&amp;(((<span style=\"color: #ff0000;\">TYPE<\/span>*)<span style=\"color: #0000ff;\">0<\/span>)-&gt;<span style=\"color: #ff0000;\">MEMBER<\/span>)<\/pre>\n<p>There are some variations on this code \ufeffusing simple subtraction as well as some formalizations using the ptr_diff type, but that\u2019s 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\u2019t 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\u2019re after; if only it could be coaxed out. Finally, I wanted to see if they knew enough about\u00a0machine code\u00a0and addressing modes to know that they weren\u2019t actually dereferencing <span style=\"font-family: courier;\">NULL<\/span> in there, and it won\u2019t crash.<\/p>\n<h2>But what about <em>offsetof<\/em>?<\/h2>\n<p>Ahh, I can already hear the more experienced engineers out there decrying my complete ignorance of the <span style=\"font-family: courier;\">offsetof<\/span> macro. No, I know it\u2019s there, and if a candidate ever brought that fact up, I would just ask them to implement it \u2013 strangely, a few people knew the answer off the top of their heads, but no one has ever mentioned  <span style=\"font-family: courier;\">offsetof<\/span>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ok, so you have your answer? First, a few questions to show you how the interview usually went: Did you just write down a number like 12? Did you use sizeof? What if the size of an integer is 8-bytes on one architecture and 4 bytes on another? What about structure packing? There\u2019s probably a <a href='https:\/\/www.myopictopics.com\/?page_id=217' class='excerpt-more'>[&#8230;]<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"open","template":"","meta":{"footnotes":""},"class_list":["post-217","page","type-page","status-publish","hentry","post-seq-1","post-parity-odd","meta-position-corners","fix"],"_links":{"self":[{"href":"https:\/\/www.myopictopics.com\/index.php?rest_route=\/wp\/v2\/pages\/217","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.myopictopics.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.myopictopics.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.myopictopics.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.myopictopics.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=217"}],"version-history":[{"count":17,"href":"https:\/\/www.myopictopics.com\/index.php?rest_route=\/wp\/v2\/pages\/217\/revisions"}],"predecessor-version":[{"id":278,"href":"https:\/\/www.myopictopics.com\/index.php?rest_route=\/wp\/v2\/pages\/217\/revisions\/278"}],"wp:attachment":[{"href":"https:\/\/www.myopictopics.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=217"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}