tags:

views:

188

answers:

4

I want to get the size of a specific member in a struct.

sizeof(((SomeStruct *) 0)->some_member) works for me but I feel like there might be a nicer way to do it.

I could #define SIZEOF_ELEM(STRUCT, ELEM) sizeof(((STRUCT *) 0)->ELEM) and then use SIZEOF_ELEM(SomeStruct, some_member), but I wonder whether there is already something better built-in.

My specific use-case is in hsc2hs (Haskell C bindings).

pokeArray (plusPtr context (#offset AVFormatContext, filename)) .
  take (#size ((AVFormatContext *) 0)->filename) .
  (++ repeat '\NUL') $ filename
+5  A: 

What you've got is about as clean as it gets if you can't guarantee you have a variable to dereference. (If you can, then use just sizeof(var.member) or sizeof(ptr->member), of course, but this won't work in some contexts where a compile-time constant is needed.)

Once upon a long, long time ago (circa 1990), I ran into a compiler that had 'offsetof' defined using the base address 0, and it crashed. I worked around the problem by hacking <stddef.h> to use 1024 instead of 0. But you should not run into such problems now.

Jonathan Leffler
+3  A: 

I believe you've already got the correct solution there. You could dig up your stddef.h and look for how offsetof is defined, since it does a very similar thing.

Remember that there may well be a difference between the sizeof a member and the difference between the offsetofs of that member and the next one, due to padding.

David Thornley
+3  A: 

In C++ you could do sizeof(SomeStruct::some_member), but this is c and you have no scope resolution operator. What you've written is as good as can be written, as far as I know.

David Seiler
+2  A: 

Microsoft has the following in one of their headers:

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

I see no reason to do any different.

They have related macros for:

RTL_SIZEOF_THROUGH_FIELD()
RTL_CONTAINS_FIELD()

and the nifty:

CONTAINING_RECORD()

which helps implement generic lists in straight C without having to require that link fields be at the start of a struct. See this Kernel Mustard article for details.

Michael Burr