offsetof
| Definiert in Header <cstddef> |
||
| #define offsetof(typ, glied) /* implementierungsabhängig */ |
||
Das Makro offsetof expandiert zu einem ganzzahligen konstanten Ausdruck vom Typ std::size_t, dessen Wert der Offset in Bytes vom Anfang eines Objekts vom angegebenen Typ zu seinem angegebenen Unterobjekt ist, einschließlich Füllbits, falls vorhanden.
Gegeben sei ein Objekt o vom Typ typ und statischer Speicherklasse, dann soll o.glied ein lvalue konstanten Ausdruck sein, der sich auf ein Unterobjekt von o bezieht. Andernfalls ist das Verhalten undefiniert. Insbesondere, wenn glied ein statisches Datenelement, ein Bitfeld oder eine Memberfunktion ist, ist das Verhalten undefiniert.
Wenn typ kein PODType(bis C++11)Typ mit Standardlayout(seit C++11) ist, ist das Ergebnis von offsetof undefiniert(bis C++17)ist die Verwendung des offsetof Makros bedingt unterstützt(seit C++17).
Der Ausdruck offsetof(typ, glied) ist niemals typunabhängig und ist nur dann wertabhängig, wenn typ abhängig ist.
Inhalt |
[bearbeiten] Ausnahmen
offsetof löst keine Ausnahmen aus.
|
Der Ausdruck noexcept(offsetof(typ, glied)) evaluiert immer zu true. |
(seit C++11) |
[bearbeiten] Hinweise
|
Der Offset des ersten Glieds eines Typs mit Standardlayout ist immer Null (die Empty-Base Optimization ist obligatorisch). |
(seit C++11) |
offsetof kann nicht in Standard-C++ implementiert werden und erfordert Compilerunterstützung: GCC, LLVM.
glied ist nicht auf ein direktes Glied beschränkt. Es kann ein Unterobjekt eines gegebenen Glieds bezeichnen, z. B. ein Element eines Array-Glieds. Dies ist durch C DR 496 spezifiziert.
In C23 ist festgelegt, dass die Definition eines neuen Typs, der ein nicht in Klammern gesetztes Komma in offsetof enthält, undefiniertes Verhalten darstellt, und eine solche Verwendung wird in C++-Modi im Allgemeinen nicht von Implementierungen unterstützt: offsetof(struct Foo { int a, b; }, a) wird von allen bekannten Implementierungen abgelehnt.
[bearbeiten] Beispiel
#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'; }
Mögliche Ausgabe
offset of char m0 = 0 offset of double m1 = 8 offset of short m2 = 16 offset of char m3 = 18
[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| CWG 273 | C++98 | offsetof funktioniert möglicherweise nicht, wenn der unäre operator& überladen ist |
muss korrekt funktionieren, auch wenn operator& überladen ist |
| LWG 306 | C++98 | das Verhalten war nicht spezifiziert, wenn typ kein PODType war |
das Ergebnis ist in diesem Fall undefiniert |
| LWG 449 | C++98 | andere Anforderungen an offsetof wurdendurch die Auflösung von LWG issue 306 entfernt |
wieder hinzugefügt |
[bearbeiten] Siehe auch
| nicht vorzeichenbehafteter Ganzzahltyp, der vom sizeof-Operator zurückgegeben wird (typedef) | |
| (C++11) |
prüft, ob ein Typ ein Standardlayout-Typ ist (Klassenvorlage) |
| C-Dokumentation für offsetof
| |