Standard macro in the C programming language
C's offsetof() macro is an ANSI C library feature found in stddef.h. It evaluates to the offset (in bytes) of a given member within a struct or union type, an expression of … Wikipedia
🌐
Wikipedia
en.wikipedia.org › wiki › Offsetof
offsetof - Wikipedia
October 29, 2025 - Usage of offsetof is limited to POD types in C++98, standard-layout classes in C++11, and more cases are conditionally-supported in C++17, otherwise it has an undefined behavior.
🌐
cppreference.com
en.cppreference.com › w › c › types › offsetof.html
offsetof - cppreference.com
March 26, 2024 - The macro offsetof expands to an integer constant expression of type size_t, the value of which is the offset, in bytes, from the beginning of an object of specified type to its specified subobject, including padding if any.
Top answer
1 of 4
51

R.. is correct in his answer to the second part of your question: this code is not advised when using a modern C compiler.

But to answer the first part of your question, what this is actually doing is:

(
  (int)(         // 4.
    &( (         // 3.
      (a*)(0)    // 1.
     )->b )      // 2.
  )
)

Working from the inside out, this is ...

  1. Casting the value zero to the struct pointer type a*
  2. Getting the struct field b of this (illegally placed) struct object
  3. Getting the address of this b field
  4. Casting the address to an int

Conceptually this is placing a struct object at memory address zero and then finding out at what the address of a particular field is. This could allow you to figure out the offsets in memory of each field in a struct so you could write your own serializers and deserializers to convert structs to and from byte arrays.

Of course if you would actually dereference a zero pointer your program would crash, but actually everything happens in the compiler and no actual zero pointer is dereferenced at runtime.

In most of the original systems that C ran on the size of an int was 32 bits and was the same as a pointer, so this actually worked.

2 of 4
21

It has no advantages and should not be used, since it invokes undefined behavior (and uses the wrong type - int instead of size_t).

The C standard defines an offsetof macro in stddef.h which actually works, for cases where you need the offset of an element in a structure, such as:

#include <stddef.h>

struct foo {
    int a;
    int b;
    char *c;
};

struct struct_desc {
    const char *name;
    int type;
    size_t off;
};

static const struct struct_desc foo_desc[] = {
    { "a", INT, offsetof(struct foo, a) },
    { "b", INT, offsetof(struct foo, b) },
    { "c", CHARPTR, offsetof(struct foo, c) },
};

which would let you programmatically fill the fields of a struct foo by name, e.g. when reading a JSON file.

🌐
TutorialsPoint
tutorialspoint.com › c_standard_library › c_macro_offsetof.htm
C library - offsetof() macro
The C library offsetof(type, member-designator) Macro results in a constant integer of type size_t which is the offset in bytes of a structure member from the beginning of the structure.
🌐
Linux Man Pages
man7.org › linux › man-pages › man3 › offsetof.3.html
offsetof(3) - Linux manual page
On a Linux/i386 system, when compiled using the default gcc(1) options, the program below produces the following output: $ ./a.out offsets: i=0; c=4; d=8 a=16 sizeof(struct s)=16 Program source #include <stddef.h> #include <stdio.h> #include <stdlib.h> int main(void) { struct s { int i; char c; double d; char a[]; }; /* Output is compiler dependent */ printf("offsets: i=%zu; c=%zu; d=%zu a=%zu\n", offsetof(struct s, i), offsetof(struct s, c), offsetof(struct s, d), offsetof(struct s, a)); printf("sizeof(struct s)=%zu\n", sizeof(struct s)); exit(EXIT_SUCCESS); }
🌐
Linux Man Pages
linux.die.net › man › 3 › offsetof
offsetof(3): offset of structure member - Linux man page
offsetof() returns the offset of the given member within the given type, in units of bytes. C89, C99, POSIX.1-2001.
🌐
GNU
gcc.gnu.org › onlinedocs › gcc › Offsetof.html
Offsetof (Using the GNU Compiler Collection (GCC))
primary: "__builtin_offsetof" "(" typename "," offsetof_member_designator ")" offsetof_member_designator: identifier | offsetof_member_designator "." identifier | offsetof_member_designator "[" expr "]"
🌐
Microsoft Learn
learn.microsoft.com › en-us › cpp › c-runtime-library › reference › offsetof-macro
offsetof Macro | Microsoft Learn
October 26, 2022 - The offsetof macro returns the offset in bytes of memberName from the beginning of the structure specified by structName as a value of type size_t.
🌐
Linuxcampus
linuxcampus.net › documentation › man-html › htmlman3 › offsetof.3.html
offsetof(3) — Linux manual pages
offsetof() returns the offset of the given member within the given type, in units of bytes. POSIX.1-2001, POSIX.1-2008, C89, C99.
Find elsewhere
🌐
Barr Group
barrgroup.com › blog › how-use-cs-offsetof-macro
How to Use C's offsetof() Macro
March 1, 2004 - The offsetof() macro returns the offset of the element name within the struct or union composite.
🌐
Cplusplus
cplusplus.com › reference › cstddef › offsetof
offsetof
No-throw guarantee: this macro never throws exceptions: noexcept(offsetof(type,member)) is always true.
🌐
GeeksforGeeks
geeksforgeeks.org › c++ › the-offsetof-macro
The OFFSETOF() macro - GeeksforGeeks
July 23, 2025 - The ultimate goal is to extract displacement of the element. We will see practical usage of offsetof macro in liked lists to connect similar objects (for example thread pool) in another article. Article compiled by Venki. References: 1. Linux Kernel code. 2. https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/offsetof-macro?redirectedfrom=MSDN 3.
🌐
Wikibooks
en.wikibooks.org › wiki › C_Programming › stddef.h › offsetof
C Programming/stddef.h/offsetof - Wikibooks, open books for an open world
#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr - offsetof(type,member) );})
🌐
Open-std
open-std.org › jtc1 › sc22 › wg21 › docs › papers › 2024 › p3407r0.html
Make idiomatic usage of `offsetof` well-defined
October 14, 2024 - A C++-only project would typically make ListNode a base class. Converting a ListNode* to a Foo* could then be done easily using static_cast, and offsetof would be unnecessary. This option is not available in C.
🌐
Cprogramming
cboard.cprogramming.com › c-programming › 40936-offsetof.html
offsetof
June 20, 2003 - It seems to be suggesting that if you have offsetof(T,m), that the compiler can fail to warn you if T is not a struct/union, or m is not a member of T. But that would mean the compiler is broken in my opinion. In C99, offsetof() is defined as having a result type of size_t.
🌐
GitHub
gist.github.com › graphitemaster › 494f21190bb2c63c5516
Working around offsetof limitations in C++ · GitHub
The most common technique for getting this information is through the offsetof macro defined in stddef.h.
🌐
Stack Overflow
stackoverflow.com › questions › 66270079 › how-macro-could-be-used-to-calculate-offset-of-fields-in-a-structure
c - How macro could be used to calculate offset of fields in a structure? - Stack Overflow
Why reinvent the wheel? The macro you're trying implement is already part of the C89/C99 standard. It's offsetof(type, member), defined in stddef.h.