One of the reasons why I tend to avoid using tagged unions is that I don't like the idea of the performance penalty that the switch/case statement for the tag might introduce if the number of tags is greater than 4 or so.
I just had the idea that instead of using a tag, one could set a pointer to a function that reads the last written value in the union. For example:
union u{
char a;
int b;
size_t c;
};
struct fntag{
void (*readval)(union u *ptr, void *out);
union u val;
};
And then, whenever you write a value into val, you also update the readval pointer accordingly, so that it points to a function that reads the last field you wrote in the union. Yes, there's a difficult issue, and it's where to return the read value (because the same function pointer cannot point to functions returning different types). I chose to return the value through a pointer to void so that such function can also be "overloaded" with C11 _Generic() and thus casting and writing into different types for the output.
Of course, invoking a pointer to a function has a performance overhead, and I guess it's far heavier that checking the value of an enum, but at some point, if the number of tags is big, I believe it would be faster than switch/case.
My question is: Have you ever seen this technique used somewhere? (I haven't, and I don't know if it's because real world application of this would require _Generic() on the readval function, which requires C11, or if it's because of some problem I'm not noticing at this moment). How many tags do you guess you'd need to have for the pointer to function being faster -in current Intel CPUs- than the switch/case?