This is similar to a common implementation of the offsetof()
macro, defined in the C standard header <stddef.h>
. The code actually has undefined behavior, but it's likely to work for most C implementations.
It yields the offset, in bytes, of item
from the beginning of type structure
. structure
should be a struct type (it could be a union, but then OFFSETOF
will always yield 0), and item
is a member of that structure (or union) type.
(structure*)0
is a null pointer of type pointer to structure
.
((structure*)0)->item
refers to the item
member of the nonexistent structure
object at the address that a null pointer points to. Yes, that's odd. If a null pointer is represented as memory address 0, and item
is at an offset of, say, 12 bytes, then the object referred to by ((structure*)0)->item
is at memory address 12. This makes a lot of assumptions about the memory model of the current system. Those assumptions are commonly valid; if they're not, this thing will probably blow up in your face.
&(((structure*)0)->item)
is the address of that mythical object at address 12.
Finally, ((u16)&(((structure*)0)->item))
is memory address 12 (of type structure*
) explicitly converted to u16
. Presumably u16
is an unsigned 16-bit integer type (if so, it would make more sense to use the standard uint16_t
).
So given a structure type structure
, and a member item
at offset 12, this macro would expand to an expression that yields the value 12.
Keep in mind that addresses (pointer values) are not numbers; they're conceptually distinct concepts. This macro will work only for systems that use a particularly memory model, one that isn't specified by the C standard.
I'm not sure why the result is of type u16
. The standard offsetof
macro yields a value of type size_t
.
For systems that use a different memory model (for example, if a null pointer is represented as all-bits-one or 0xdeadbeef
), this OFFSETOF
macro would not work, and the standard offsetof
macro would have to tailored to work on that particular system. That's part of the reason offsetof
is in the standard library, so it can be implemented in a way that works on each system.