C: mejor manera de hacer sizeof (((SomeStruct *) 0) - > some_member)?

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

  •  06-07-2019
  •  | 
  •  

Pregunta

Quiero obtener el tamaño de un miembro específico en una estructura.

sizeof (((SomeStruct *) 0) - > some_member) funciona para mí, pero creo que podría haber una mejor manera de hacerlo.

Podría #define SIZEOF_ELEM (STRUCT, ELEM) sizeof (((STRUCT *) 0) - > ELEM) y luego usar SIZEOF_ELEM (SomeStruct, some_member) , pero me pregunto si ya hay algo mejor incorporado.

Mi caso de uso específico está en hsc2hs (enlaces Haskell C).

pokeArray (plusPtr context (#offset AVFormatContext, filename)) .
  take (#size ((AVFormatContext *) 0)->filename) .
  (++ repeat '\NUL') $ filename
¿Fue útil?

Solución

Lo que tienes es lo más limpio posible si no puedes garantizar que tienes una variable para desreferenciar. (Si puede, use solo sizeof (var.member) o sizeof (ptr- > member) , por supuesto, pero esto no funcionará en algunos contextos donde se necesita una constante de tiempo de compilación.)

Hace mucho, mucho tiempo (alrededor de 1990), me encontré con un compilador que tenía ' offsetof ' definido usando la dirección base 0, y se bloqueó. Solucioné el problema pirateando < stddef.h > para usar 1024 en lugar de 0. Pero ahora no debería tener tales problemas.

Otros consejos

Creo que ya tienes la solución correcta allí. Puede desenterrar su stddef.h y buscar cómo se define offsetof, ya que hace algo muy similar.

Recuerde que bien puede haber una diferencia entre el tamaño de un miembro y la diferencia entre los desplazamientos de ese miembro y el siguiente, debido al relleno.

En C ++ puede hacer sizeof (SomeStruct :: some_member), pero esto es c y no tiene un operador de resolución de alcance. Lo que has escrito es tan bueno como se puede escribir, que yo sepa.

Microsoft tiene lo siguiente en uno de sus encabezados:

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

No veo ninguna razón para hacer algo diferente.

Tienen macros relacionadas para:

RTL_SIZEOF_THROUGH_FIELD()
RTL_CONTAINS_FIELD()

y el ingenioso:

CONTAINING_RECORD() 

que ayuda a implementar listas genéricas en C sin tener que requerir que los campos de enlace estén al comienzo de una estructura. Consulte este artículo Kernel Mustard para obtener más detalles.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top