offsetof
| Definiert in Header <cstddef>
|
||
#define offsetof(type, member) /* implementation-defined */
|
||
Das Makro offsetof wird zu einem ganzzahligen konstanten Ausdruck des Typs std::size_t expandiert, dessen Wert der Offset in Bytes vom Beginn eines Objekts des angegebenen Typs zu seinem angegebenen Unterobjekt ist, einschließlich etwaiger Padding-Bits.
Gegeben sei ein Objekt o vom Typ type und mit statischer Speicherdauer, o.member muss ein lvalue-konstanter Ausdruck sein, der auf ein Unterobjekt von o verweist. Andernfalls ist das Verhalten undefiniert. Insbesondere ist das Verhalten undefiniert, wenn member ein statisches Datenelement, ein Bitfeld oder eine Mitgliedsfunktion ist.
Wenn type kein PODType(bis C++11)Standard-Layout-Typ(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(type, member) ist niemals typabhängig und er ist genau dann wertabhängig, wenn type abhängig ist.
Ausnahmen
offsetof
wirft keine Ausnahmen.
|
Der Ausdruck noexcept ( offsetof ( type, member ) ) ergibt immer true . |
(seit C++11) |
Hinweise
|
Der Offset des ersten Members eines Standard-Layout-Typs ist immer null ( Empty-Base Optimization ist verpflichtend). |
(seit C++11) |
offsetof
kann nicht in Standard-C++ implementiert werden und erfordert Compiler-Unterstützung:
GCC
,
LLVM
.
member
ist nicht auf ein direktes Mitglied beschränkt. Es kann ein Unterobjekt eines bestimmten Mitglieds bezeichnen, wie beispielsweise ein Element eines Array-Mitglieds. Dies wird durch
C DR 496
spezifiziert.
In C23 ist festgelegt, dass die Definition eines neuen Typs mit einem nicht in Klammern gesetzten Komma in
offsetof
undefiniertes Verhalten darstellt, und solche Verwendungen werden allgemein nicht von Implementierungen in C++-Modi unterstützt:
offsetof
(
struct
Foo
{
int
a, b
;
}
, a
)
wird von allen bekannten Implementierungen abgelehnt.
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
Fehlerberichte
Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | Angewendet auf | Verhalten wie veröffentlicht | Korrektes Verhalten |
|---|---|---|---|
| CWG 273 | C++98 |
offsetof
funktioniert möglicherweise nicht, wenn der unäre
operator&
überladen ist
|
muss auch dann korrekt funktionieren,
wenn
operator&
überladen ist
|
| LWG 306 | C++98 |
das Verhalten war nicht spezifiziert, wenn
type
kein
PODType
ist
|
das Ergebnis ist in diesem Fall undefiniert |
| LWG 449 | C++98 |
andere Anforderungen an
offsetof
wurden
durch die Lösung von LWG issue 306 entfernt |
wieder hinzugefügt |
Siehe auch
|
vorzeichenloser Ganzzahltyp, zurückgegeben vom
sizeof
Operator
(typedef) |
|
|
(C++11)
|
prüft, ob ein Typ ein
Standard-Layout
Typ ist
(Klassentemplate) |
|
C-Dokumentation
für
offsetof
|
|