C: meilleure façon de faire sizeof (((SomeStruct *) 0) - > some_member)?

StackOverflow https://stackoverflow.com/questions/1014750

  •  06-07-2019
  •  | 
  •  

Question

Je souhaite obtenir la taille d'un membre spécifique dans une structure.

sizeof (((SomeStruct *) 0) - > some_member) fonctionne pour moi, mais j’ai l’impression qu’il pourrait exister une méthode plus agréable.

Je pourrais #define SIZEOF_ELEM (STRUCT, ELEM) sizeof (((STRUCT *) 0) - > ELEM) , puis utiliser SIZEOF_ELEM (SomeStruct, some_member) , mais je me demande s’il existe déjà quelque chose de mieux intégré.

Mon cas d'utilisation spécifique se trouve dans hsc2hs (liaisons Haskell C).

pokeArray (plusPtr context (#offset AVFormatContext, filename)) .
  take (#size ((AVFormatContext *) 0)->filename) .
  (++ repeat '\NUL') $ filename
Était-ce utile?

La solution

Ce que vous avez est à peu près aussi propre qu’il devient si vous ne pouvez pas garantir que vous avez une variable à déréférencer. (Si vous le pouvez, utilisez simplement sizeof (var.member) ou sizeof (ptr- > membre) , bien sûr, mais cela ne fonctionnera pas dans certains contextes. où une constante de compilation est nécessaire.)

Il était une fois, très longtemps (environ 1990), je suis tombé sur un compilateur qui avait ' offsetof ' défini à l'aide de l'adresse de base 0 et il s'est écrasé. J'ai résolu le problème en piratant < stddef.h > pour utiliser 1024 au lieu de 0. Mais vous ne devriez pas rencontrer de tels problèmes maintenant.

Autres conseils

Je pense que vous avez déjà trouvé la bonne solution. Vous pouvez déterrer votre stddef.h et voir comment offsetof est défini, car il a une action très similaire.

N'oubliez pas qu'il peut très bien y avoir une différence entre la taille d'un membre et la différence entre les offsetofs de ce membre et du suivant, en raison du remplissage.

En C ++, vous pouvez faire sizeof (SomeStruct :: some_member), mais c’est c et vous n’avez pas d’opérateur de résolution de périmètre. Ce que vous avez écrit est aussi bon que possible, à ma connaissance.

Microsoft a l'un des en-têtes suivants:

#define RTL_FIELD_SIZE(type, field) (sizeof(((type *)0)->field))

Je ne vois aucune raison de faire autrement.

Ils ont des macros associées pour:

RTL_SIZEOF_THROUGH_FIELD()
RTL_CONTAINS_FIELD()

et le chouette:

CONTAINING_RECORD() 

qui aide à implémenter des listes génériques dans le straight C sans avoir à exiger que les champs de lien soient au début d'une structure. Consultez cet article sur le noyau Mustard pour plus de détails. / p>

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top