offsetof
|
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) |
|
|
(C++11)
|
verifica si un tipo es un tipo de
diseño estándar
(plantilla de clase) |
|
Documentación de C
para
offsetof
|
|