2010-08-10 29 views
0

dans le code source qemu, j'ai la macro suivante offsetof. Quelqu'un peut-il me dire ce qu'il fait?Que fait la macro suivante?

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *) 0)->MEMBER) 

Il est utilisé de cette manière:

offsetof(CPUState, icount_decr.u32) 

où CPUState est un struct.

Je pense qu'il donne le décalage du membre à l'intérieur d'une structure, mais je ne suis pas sûr.

EDIT: Oui, j'ai découvert ce qui se passait. La définition de CPUState avait une macro à l'intérieur, que j'ai manquée, qui comprenait la variable icount_decr.

+1

http://en.wikipedia.org/wiki/Offsetof –

+1

La macro déclenche techniquement un comportement indéfini, mais arrive à travailler dans beaucoup d'endroits. Un moderne (par exemple GCC 4) '' le définira à un compilateur intrinsèque pour éviter l'indéfini et aussi des maux de tête C++. – zwol

+0

@Zack: Comme je l'ai dit sur une réponse, c'est une fonction de bibliothèque, donc non, ce n'est pas un comportement indéfini. Une implémentation est libre de l'implémenter comme bon lui semble. (Essentiellement, cette implémentation spécifique oblige à prendre l'adresse d'un pointeur nul déréférencé pour un compilateur particulier.) – GManNickG

Répondre

1

Votre avis est correct! Et le nom de la macro donne aussi un bon indice. ;)

3

Il obtient le décalage du membre d'une structure. Il le fait en castant l'adresse zéro à une structure de ce type prenant alors l'adresse du membre.

+0

Les compilateurs C/C++ ajoutent dernièrement une fonction intrinsèque, principalement parce que vous pouvez casser cette technique avec des opérateurs surchargés en C++, mais aussi parce que c'est * un comportement techniquement indéfini et vous pouvez imaginer un point d'attaque il. – zwol

+0

@Zack: C'est une fonctionnalité de bibliothèque, donc non, ce n'est pas un comportement indéfini. Une implémentation est libre de l'implémenter comme bon lui semble. – GManNickG

+1

Il implique que cette macro est définie à l'intérieur d'un programme d'application, auquel cas il s'agit d'un comportement indéfini (bien qu'il soit extrêmement probable que cela fonctionne normalement). Si la définition était dans la bibliothèque standard, elle ne serait pas indéfinie bien sûr. – jcoder

0

Il est défini dans §7.17/3:

offsetof(type, member-designator)
qui se dilate à un nombre entier expression constante qui est de type size_t, la valeur de qui est le décalage en octets, à l'élément de structure (désigné par membre-désignateur), depuis le début de sa structure (désigné par type). Le désignateur de type et membre doit être tel que donné
static type t;
alors l'expression &(t.member-designator) évalue à une constante d'adresse. (Si le membre spécifié est un peu sur le terrain, le comportement est indéfini.)

Parce que la bibliothèque ne doit pas nécessairement suivre des règles linguistiques, une mise en œuvre est libre d'obtenir le résultat qui lui plaît. Par conséquent, le résultat de cette implémentation particulière est et non comportement non défini, car vous n'êtes pas censé vous soucier de la façon dont il est implémenté. (En d'autres termes, votre implémentation garantit que la prise d'adresse d'une adresse indirecte via un pointeur nul est bien définie.) Bien sûr, vous ne pouvez pas supposer cela dans vos propres programmes.)

Si une bibliothèque a (re) défini offsetof, ils ont rendu le comportement de votre programme indéfini et devraient utiliser la bibliothèque standard à la place. (Les mannequins.)