问题
I am struggling with using unions. Why am I unable to pass the function pointer to where the union would be? Any help would be greatly appreciated.
Edit: removed a typedef
#include <stdio.h>
union U {
int(*fnPtr)(int);
int i;
};
enum E {
OPTION_0 = 0,
OPTION_1 = 1
};
int multiply_by_two (int x) {
return 2 * x;
}
int f (int x, enum E e, union U u) {
switch (e) {
case OPTION_0:
/* Return the sum */
return x + u.i;
case OPTION_1:
/* Return 2 * x */
return u.fnPtr (x);
}
}
int main (void) {
int a;
scanf ("%d", &a);
int b = f (a, OPTION_1, &multiply_by_two);
printf ("%d\n", b);
return 0;
}
回答1:
First, this definition is not valid:
union U {
typedef int(*fnPtr)(int);
int i;
};
You can't have a typedef
inside of a struct
or union
. Removing the typedef will give you a proper definition:
union U {
int(*fnPtr)(int);
int i;
};
The second problem is here:
int b = f (a, OPTION_1, &multiply_by_two);
The function f
expects a union U
, but you're passing it a int (*)(int)
. Those types are not compatible. Just because the union has a member of that type doesn't mean you can use that type wherever you would use the union. You need to create a union, set the proper field, then pass that to the function.
union U u;
u.fnPtr = multiply_by_two;
int b = f (a, OPTION_1, u);
回答2:
In main function, try this:
int main()
{
...
union U myUnion;
myUnion.fnPtr = &multiply_by_two;
int b = f (a, OPTION_1, myUnion);
...
}
And also, the union definition is not correct, you need to remove typedef
.
回答3:
Just to add to other answers: this is usually called a variant data type, and it makes sense to keep the type enum in a struct
, along with the union
, since you will be passing it around all the time anyway.
So I would recommend placing both in a struct
:
enum var_type
{
VAR_INT = 0,
VAR_FUNC = 1
};
struct variant
{
// contains the type of the stored value
enum var_type type;
// contains the actual value
union {
int(*fnPtr)(int);
int i;
};
};
And then you can have separate functions for creating each subtype, for simpler instantiation:
// wrap the int value in the variant struct
struct variant variant_create_int(int i)
{
return (struct variant){ .type = VAR_INT, .i = i };
}
// wrap the functino pointer in the variant struct
struct variant variant_create_func(int(*fnPtr)(int))
{
return (struct variant){ .type = VAR_FUNC, .fnPtr = fnPtr };
}
Meaning your main
would do something like:
// create variant of type 'VAR_FUNC'
struct variant var = variant_create_func(&multiply_by_two);
and just pass the var
struct forward.
来源:https://stackoverflow.com/questions/54517241/union-of-value-and-function-pointer