Namespaces
Variants

offsetof

From cppreference.net
Utilities library
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)
vérifie si un type est un type à disposition standard
(modèle de classe)
documentation C pour offsetof