c - Let a macro count its invocations -
i've huge c project module reading , managing configuration data. if have add new configuration parameter, i'll have edit several functions, e.g. pseudo-code:
void read_configuration(config *c) { read_param("p1", c->p1); read_param("p2", c->p2); read_param("p3", c->p3); /* ... */ } void dump_configuration(config *c) { dump_param("p1", c->p1); dump_param("p2", c->p2); dump_param("p3", c->p3); /* ... */ }
is there way ensure macro at compile time, each location has @ least same count of parameters? thought of making dump_param
kind of macro counting invocations , add like
#if nr_read != nr_dump #error "you forgot something, idiot!" #endif
at end of module. can't find method make macro count invocations, though...
since list of parameters same in both functions, how factoring that out , avoid possible mismatch ?
using x-macros
#define x_config_params(config) \ x("p1", (config).p1) \ x("p2", (config).p2) \ x("p3", (config).p3) void read_configuration(config *c) { #define x(name, param) read_param(name, ¶m); x_config_params(*c) #undef x } void dump_configuration(config *c) { #define x(name, param) dump_param(name, ¶m); x_config_params(*c) #undef x }
using function pointers
void alter_config(config *c, void(*func)(char const *name, param *param)) { func("p1", &c->p1); func("p2", &c->p2); func("p3", &c->p3); } void read_configuration(config *c) { alter_config(c, read_param); } void dump_configuration(config *c) { alter_config(c, dump_param); }
using array , offsetof
struct param_info { char const *name; size_t config_offs; }; param_info allparams[] = { {"p1", offsetof(config, p1)}, {"p2", offsetof(config, p2)}, {"p3", offsetof(config, p3)} }; void read_configuration(config *c) { size_t paramcount = sizeof allparams / sizeof *allparams; for(size_t = 0; < paramcount; ++i) { param *p = (param*)((char*)config + allparams[i].config_offs); read_param(allparams[i].name, p); } } void dump_configuration(config *c) { size_t paramcount = sizeof allparams / sizeof *allparams; for(size_t = 0; < paramcount; ++i) { param *p = (param*)((char*)config + allparams[i].config_offs); dump_param(allparams[i].name, p); } }
Comments
Post a Comment