Spec-Zone.ru › C++

offsetof

Определено в заголовочном файле <cstddef>
#define offsetof(type, member) /* implementation-defined */

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

Для объекта o типа type со статической длительностью хранения o.member должно быть константным выражением-ссылкой на подобъект 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)

Примечания

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

(с 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 Применён к Поведение, как опубликовано Корректное поведение
CWG 273 C++98 offsetof может не работать, если унарный operator& перегружен требуется работать корректно даже
если operator& перегружен
LWG 306 C++98 поведение не было определено, когда type не является типом POD результат не определён в этом случае
LWG 449 C++98 другие требования к offsetof были
удалены решением LWG issue 306
они были добавлены обратно

См. также

size_t
целого типа без знака, возвращаемого оператором sizeof
(typedef)
is_standard_layout
(C++11)
проверяет, является ли тип типом стандартного расположения
(шаблон класса)
C документация по offsetof

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API