offsetof
| Definido en el encabezado <cstddef>
|
||
#define offsetof(type, member) /* implementation-defined */
|
||
La macro offsetof se expande a una expresión constante integral 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 y duración de almacenamiento estático, o.member será una expresión constante lvalue que se refiera a un subobjeto de o. De lo contrario, el comportamiento no está definido. En particular, si member es un miembro de datos estático, un campo de bits o una función miembro, el comportamiento no está definido.
Si type no es un tipo POD(hasta C++11)tipo de diseño estándar(desde C++11), el resultado de offsetof no está definido(hasta C++17)el uso de la macro offsetof tiene soporte condicional(desde C++17).
La expresión offsetof(type, member) nunca es dependiente del tipo y es dependiente del valor si y solo si type es dependiente.
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
|
|