Namespaces
Variants

offsetof

From cppreference.net
Utilities library
Definido en el encabezado <cstddef>
#define offsetof(type, member) /* implementation-defined */

La macro offsetof se expande a una expresión constante entera de tipo std::size_t , cuyo valor es el desplazamiento, en bytes, desde el inicio de un objeto del tipo especificado hasta su subobjeto especificado, incluyendo bits de relleno si los hay.

Dado un objeto o de tipo type con duración de almacenamiento estático, o. member será una expresión constante lvalue que se refiere a un subobjeto de o . De lo contrario, el comportamiento es indefinido. En particular, si member es un miembro de datos estático , un campo de bits , o una función miembro , el comportamiento es indefinido.

Si type no es un PODType (hasta C++11) tipo de diseño estándar (desde C++11) , el resultado de offsetof es indefinido (hasta C++17) el uso de la macro offsetof es condicionalmente soportado (desde C++17) .

La expresión offsetof ( type, member ) nunca es dependiente de tipo y es dependiente de valor si y solo si type es dependiente.

Contenidos

Excepciones

offsetof no lanza excepciones.

La expresión noexcept ( offsetof ( type, member ) ) siempre se evalúa como true .

(desde C++11)

Notas

El desplazamiento del primer miembro de un tipo de diseño estándar siempre es cero ( la optimización de base vacía es obligatoria).

(desde C++11)

offsetof no se puede implementar en C++ estándar y requiere soporte del compilador: GCC , LLVM .

member no está restringido a un miembro directo. Puede denotar un subobjeto de un miembro dado, como un elemento de un miembro array. Esto está especificado por C DR 496 .

Se especifica en C23 que definir un nuevo tipo que contenga una coma sin paréntesis en offsetof es comportamiento indefinido, y dicho uso generalmente no es compatible con las implementaciones en modos C++: offsetof ( struct Foo { int a, b ; } , a ) es rechazado por todas las implementaciones conocidas.

Ejemplo

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

Salida posible:

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

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
CWG 273 C++98 offsetof podría no funcionar si el operador unario operator& está sobrecargado debe funcionar correctamente incluso
si operator& está sobrecargado
LWG 306 C++98 el comportamiento no estaba especificado cuando type no es un PODType el resultado es indefinido en este caso
LWG 449 C++98 otros requisitos de offsetof fueron
eliminados por la resolución de LWG issue 306
se agregaron nuevamente

Véase también

tipo entero sin signo devuelto por el operador sizeof
(typedef)
verifica si un tipo es un tipo de diseño estándar
(plantilla de clase)
Documentación de C para offsetof