Is there a way of knowing the type of a struct member at compile time? Something analogous to offsetof()
, but for types.
Eg. something like:
typedef struct{
int b;
char c;
}a_t;
typeof(a_t,b) a_get_b(void* data){
return *(typeof(a_t,b)*)(data offsetof(a_t,b));
}
CodePudding user response:
If you're willing to use typeof
(which is currently a very common nonstandard C extension slated for inclusion in the next version of the standard), you can apply it to a member obtained from a compound literal as in typeof((a_t){0}.b)
:
typedef struct{ int b; char c; }a_t;
typeof((a_t){0}.b) a_get_b(void* data){ return (a_t*){data}->b; }
(Given a type a_t
, (a_t){0}
is a reliable way to get an instance of it. Because of how initialization works in C, the 0 will initialize a deepest first elementary member and elementary types are scalars and therefore 0-initializable.)
As for the obtaining the member from a void pointer pointing to the container, you could do:
*(typeof(&(a_t){0}.b)((char*)data offsetof(a_t,b))
but that's just an awfully long-winded way to do:
(a_t*){data}->b
(which is 100% equivalent to the former as long as the effective type of data
is indeed a_t*
).
CodePudding user response:
Another way (other than Jerry Jeremiah's) is:
#define struct_get(STRUCT,ELEM) *(typeof(STRUCT.ELEM)*) (STRUCT offsetof(typeof(STRUCT),ELEM))