W3cubDocs

/C++

offsetof

Defined in header <cstddef>
#define offsetof(type, member) /* implementation-defined */

The macro offsetof expands to an integral constant expression of type std::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 bits if any.

Given an object o of type type and static storage duration, o.member shall be an lvalue constant expression that refers to a subobject of o. Otherwise, the behavior is undefined. Particularly, if member is a static data member, a bit-field, or a member function, the behavior is undefined.

If type is not a PODType (until C++11)standard layout type (since C++11), the result of offsetof is undefined (until C++17)use of the offsetof macro is conditionally-supported (since C++17).

The expression offsetof(type, member) is never type-dependent and it is value-dependent if and only if type is dependent.

Exceptions

offsetof throws no exceptions.

The expression noexcept(offsetof(type, member)) always evaluates to true.

(since C++11)

Notes

The offset of the first member of a standard-layout type is always zero (empty-base optimization is mandatory).

(since C++11)

offsetof cannot be implemented in standard C++ and requires compiler support: GCC, LLVM.

member is not restricted to a direct member. It can denote a subobject of a given member, such as an element of an array member. This is specified by C DR 496.

It is specified in C23 that defining a new type in offsetof is undefined behavior, and such usage is only partially supported by some implementations in C++ modes: offsetof(struct Foo { int a; }, a) is supported by ICC and some old versions of GCC, while offsetof(struct Foo { int a, b; }, a) is rejected by all known implementations because of the comma in the definition of Foo.

Example

#include <cstddef>
#include <iostream>
 
struct S
{
    char   m0;
    double m1;
    short  m2;
    char   m3;
//  private: int z; // warning: 'S' is a non-standard-layout type
};
 
int main()
{
    std::cout
        << "offset of char   m0 = " << offsetof(S, m0) << '\n'
        << "offset of double m1 = " << offsetof(S, m1) << '\n'
        << "offset of short  m2 = " << offsetof(S, m2) << '\n'
        << "offset of char   m3 = " << offsetof(S, m3) << '\n';
}

Possible output:

offset of char   m0 = 0
offset of double m1 = 8
offset of short  m2 = 16
offset of char   m3 = 18

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
CWG 273 C++98 offsetof may not work if unary operator& is overloaded required to work correctly even
if operator& is overloaded
LWG 306 C++98 the behavior was not specified when type is not a PODType the result is undefined in this case
LWG 449 C++98 other requirements of offsetof were
removed by the resolution of LWG issue 306
added them back

See also

unsigned integer type returned by the sizeof operator
(typedef)
(C++11)
checks if a type is a standard-layout type
(class template)
C documentation for offsetof

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/types/offsetof