Namespaces
Variants
Views
Actions

offsetof

From cppreference.com
< cpp‎ | types
 
 
Utilities library
Language support
Type support (basic types, RTTI)
Library feature-test macros (C++20)
Dynamic memory management
Program utilities
Coroutine support (C++20)
Variadic functions
Debugging support
(C++26)
Three-way comparison
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
General utilities
Date and time
Function objects
Formatting library (C++20)
(C++11)
Relational operators (deprecated in C++20)
Integer comparison functions
(C++20)(C++20)(C++20)   
(C++20)
Swap and type operations
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Common vocabulary types
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
Elementary string conversions
(C++17)
(C++17)

 
 
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.

Contents

[edit] Exceptions

offsetof throws no exceptions.

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

(since C++11)

[edit] 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 containg an unparenthesized comma in offsetof is undefined behavior, and such usage is generally not supported by implementations in C++ modes: offsetof(struct Foo { int a, b; }, a) is rejected by all known implementations.

[edit] 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

[edit] 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

[edit] See also

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