Reputation: 57
I'm trying to define a generic/macro function that sets a property of a union i've defined. I've worked with macros before, but never tried to pass multiple arguments. In this case I got a union which represents a variable (Nothing really interesting) and I want to have a single set function that allows me to set the correct property of the union's instance without specifying the datatype. This is my code:
// represents a variable
union Var {
float f;
char *s;
bool b;
// 'f' 's' or 'b'
char type;
};
// setter
void set_int(union Var *var, int newval) { var->f = (float)newval; var->type = 'f'; }
void set_float(union Var *var, float newval) { var->f = newval; var->type = 'f'; }
void set_char(union Var *var, char newval) { var->s = (char[2]){newval, 0}; var->type = 's'; }
void set_string(union Var *var, char *newval) { var->s = newval; var->type = 's'; }
void set_bool(union Var *var, bool newval) { var->b = newval; var->type = 'b'; }
#define set(VAR, X) \
_Generic((X), \
int: set_int(union Var, X), \
float: set_float(union Var), \
char: set_char(union Var), \
char *: set_string(union Var), \
bool: set_bool(union Var))(X)
int main(void) {
union Var myvar;
// myvar.f = 1.5; myvar.type = 'f'; works, but i want to do this instead:
set(&myvar, 1.5);
return 0;
}
the output that i'm getting:
var.c: In function ‘main’:
var.c:92:18: error: expected expression before ‘union’
int: set_int(union Var, X), \
^~~~~
var.c:117:5: note: in expansion of macro ‘set’
set(&myvar, 1.5);
^~~
var.c:92:10: error: too few arguments to function ‘set_int’
int: set_int(union Var, X), \
^~~~~~~
var.c:117:5: note: in expansion of macro ‘set’
set(&myvar, 1.5);
^~~
var.c:85:6: note: declared here
void set_int(union Var *var, int newval) { var->f = newval; var->type = 'f'; }
^~~~~~~
I'm getting desparate, so any help would be appreciated a lot!
PS: I'm not great at C at all, so don't burn me down if I'm making a stupid mistake. :)
Upvotes: 3
Views: 229
Reputation: 223739
Your macro is expanding to pass a type name for the first parameter to the function, which is not valid syntax. You want instead to pass whatever the VAR
parameter is:
#define set(VAR, X) \
_Generic((X), \
int: set_int, \
float: set_float, \
double: set_float, \
char: set_char, \
char *: set_string, \
bool: set_bool)((VAR), (X))
Upvotes: 3