offsetof
|
Défini dans l'en-tête
<cstddef>
|
||
|
#define offsetof(type, member) /* implementation-defined */
|
||
La macro offsetof s'étend en une expression constante entière de type std::size_t , dont la valeur est le décalage, en octets, depuis le début d'un objet d'un type spécifié jusqu'à son sous-objet spécifié, incluant les bits de remplissage le cas échéant.
Étant donné un objet
o
de type
type
et de durée de stockage statique,
o.
member
doit être une expression constante lvalue qui se réfère à un sous-objet de
o
. Sinon, le comportement est indéfini. En particulier, si
member
est un
membre de données statique
, un
champ de bits
, ou une
fonction membre
, le comportement est indéfini.
Si
type
n'est pas un
PODType
(jusqu'en C++11)
type standard-layout
(depuis C++11)
,
le résultat de
offsetof
est indéfini
(jusqu'en C++17)
l'utilisation de la macro
offsetof
est conditionnellement supportée
(depuis C++17)
.
L'expression
offsetof
(
type, member
)
n'est jamais
dépendante du type
et elle est dépendante de la valeur si et seulement si
type
est dépendant.
Table des matières |
Exceptions
offsetof
ne lève aucune exception.
|
L'expression noexcept ( offsetof ( type, member ) ) s'évalue toujours à true . |
(depuis C++11) |
Notes
|
Le décalage du premier membre d'un type de disposition standard est toujours zéro ( l'optimisation de base vide est obligatoire). |
(depuis C++11) |
offsetof
ne peut pas être implémenté en C++ standard et nécessite un support du compilateur :
GCC
,
LLVM
.
member
n'est pas limité à un membre direct. Il peut désigner un sous-objet d'un membre donné, tel qu'un élément d'un membre tableau. Ceci est spécifié par
C DR 496
.
Il est spécifié dans C23 que définir un nouveau type contenant une virgule non parenthésée dans
offsetof
est un comportement indéfini, et cette utilisation n'est généralement pas prise en charge par les implémentations en modes C++ :
offsetof
(
struct
Foo
{
int
a, b
;
}
, a
)
est rejeté par toutes les implémentations connues.
Exemple
#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'; }
Sortie possible :
offset of char m0 = 0 offset of double m1 = 8 offset of short m2 = 16 offset of char m3 = 18
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement tel que publié | Comportement correct |
|---|---|---|---|
| CWG 273 | C++98 |
offsetof
pouvait ne pas fonctionner si l'opérateur unaire
operator&
était surchargé
|
requis de fonctionner correctement même
si
operator&
est surchargé
|
| LWG 306 | C++98 |
le comportement n'était pas spécifié quand
type
n'est pas un
PODType
|
le résultat est indéfini dans ce cas |
| LWG 449 | C++98 |
les autres exigences de
offsetof
étaient
supprimées par la résolution de LWG issue 306 |
les a réintégrées |
Voir aussi
|
type entier non signé retourné par l'opérateur
sizeof
(typedef) |
|
|
(C++11)
|
vérifie si un type est un type à
disposition standard
(modèle de classe) |
|
documentation C
pour
offsetof
|
|