Namespaces
Variants

offsetof

С сайта ru.cppreference.net
 
 
Библиотека утилит
Поддержка языка
Поддержка типов (базовые типы, RTTI)
Макросы тестирования возможностей библиотеки (C++20)
Утилиты программы
Функции с переменным числом аргументов
Поддержка корутин (C++20)
Поддержка контрактов (C++26)
Трёхстороннее сравнение
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Общие утилиты
Операторы отношений (устарело в C++20)
 
 
Определён в заголовке <cstddef>
#define offsetof(type, member) /* implementation-defined */

Макрос offsetof раскрывается в целочисленное константное выражение типа std::size_t, значение которого представляет собой смещение в байтах от начала объекта указанного типа до указанного подобъекта, включая заполняющие биты, если таковые имеются.

Если дан объект o типа type со статической длительностью хранения, o.member должно быть lvalue-константным выражением, которое ссылается на подобъект o. В противном случае поведение не определено. В частности, если member является статическим элементом данных, битовым полем или функцией-членом, поведение не определено.

Если type не является POD-типом(до C++11)типом со стандартной компоновкой(начиная с C++11), результат offsetof не определён(до C++17)использование макроса offsetof условно поддерживается(начиная с C++17).

Выражение offsetof(type, member) никогда не является зависимым от типа и является зависимым от значения только в том случае, если type является зависимым.

Исключения

offsetof не генерирует исключений.

Выражение noexcept ( offsetof ( type, member ) ) всегда вычисляется в true .

(начиная с C++11)

Примечания

Смещение первого члена стандартно-компонуемого типа всегда равно нулю ( оптимизация пустого базового класса является обязательной).

(since C++11)

offsetof не может быть реализован в стандартном C++ и требует поддержки компилятора: GCC , LLVM .

member не ограничивается прямым членом. Он может обозначать подобъект заданного члена, такой как элемент члена-массива. Это указано в C DR 496 .

В стандарте C23 указано, что определение нового типа, содержащего непомещенную в скобки запятую в offsetof , является неопределенным поведением, и такая практика обычно не поддерживается реализациями в режимах C++: offsetof ( struct Foo { int a, b ; } , a ) отвергается всеми известными реализациями.

Пример

#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';
}

Возможный вывод:

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

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Applied to Behavior as published Correct behavior
CWG 273 C++98 offsetof может не работать, если унарный operator& перегружен требуется корректная работа даже
если operator& перегружен
LWG 306 C++98 поведение не было определено, когда type не является PODType результат не определён в этом случае
LWG 449 C++98 другие требования к offsetof были
удалены решением LWG issue 306
возвращены обратно

Смотрите также

беззнаковый целочисленный тип, возвращаемый оператором sizeof
(typedef)
проверяет, является ли тип стандартным размещением
(шаблон класса)