Here is a structure used in a program:
struct basic_block
{
void * aux;
/* Many other fields,
which are irrelevant. */
};
Now:
basic_block
exist during the execution of the program.aux
field is meant for storing stage and basic_block
specific data during the execution of a stage, and freed by the stage itself (so the next stage can reuse it). This is why it is a void *
.My stage uses aux
to store a struct
, so each time I want to access something, I have to do a cast:
( (struct a_long_struct_name *) (bb->aux))->foo_field = foo;
Now, my problem: Casting it each time like this is a pain, and difficult to read when it is part of more complicated expressions. My proposed solution was: Use a macro to do the cast for me:
#define MY_DATA(bb) \
( (struct a_long_struct_name *) (bb)->aux)
Then I can access my data with:
MY_DATA(bb)->foo_field = foo;
But: I cannot use MY_DATA(bb)
itself as an L-value (for a malloc
), so I using that macro isn't such a good idea after all:
/* WRONG! I cannot assign to the result of a cast: */
MY_DATA(bb) = malloc (sizeof (struct a_long_struct_name));
My question:
What can I do in order to refer to aux
in a clean way and still be able to use it as an L-value.
You can cast the address of the field to struct a_long_struct_name **
and then dereference it:
#define MY_DATA(bb) \
(* ((struct a_long_struct_name **) &(bb)->aux) )
This will work in both the constructs you have shown.
If the set of possibilities for the concrete type of aux
can be known at the point where struct basic_block
is declared, though, it would be cleaner to use a union:
struct basic_block
{
union {
struct a_long_struct_name *alsn;
/* etc */
} aux;
/* Many other fields,
which are irrelevant. */
};
and then
#define MY_DATA(bb) ((bb)->aux.alsn)