I have a number of functions that need to be called when the program is executed in order to find out the capabilities of the device that the program uses. I thought that this would be a great example to use a union of function pointers. Here's a snippet of the code that should explain what I'm going for :
struct multi_fn
{
union
{
void (*type1)(float);
void (*type2)(unsigned char*);
} func_ptr;
enum
{ FUNC_TYPE1, FUNC_TYPE2 } func_type;
};
void type1func(float);
void type2func(unsigned char*);
static const struct multi_fn the_funcs[] = {
{ { .type1 = type1func }, FUNC_TYPE1 },
{ { .type2 = type2func }, FUNC_TYPE2 }
};
As you can see, initialization of the union in this example is achieved by the means of .type1 = type1func
. However, this syntax is not valid C90 : although gcc accepts it, only issuing a warning when -pedantic
is on, MSVC refuses to compile such code.
I'm having trouble in finding another way around it : obviously, the best way to do this would be to use a struct
instead of an union
, and that's probably what I'm going to do if there is no better way. The array is going to be filled with compile-time constants only, which is pretty much the whole motivation behind it.
Knowing that C90 only allows to initialize the first member of a union
, it seems to me that they're not of much use in a case like this : even if I wanted to initialize only the first member of the union, and later access it via its other member (since the written-to type can be determined via the accompanying enum value), it would still be undefined behaviour.
I thought about storing the function pointer as a void*
and then casting it to its proper type via the enum value, however casting function pointers to void*
is also forbidden.
The question is : is there another way to do such a thing? C90 is, unfortunately, a must.