urz*_*eit 3 c macros c-preprocessor
我有一个庞大的C项目,其中包含模块读取和管理配置数据.如果我必须添加一个新的配置参数,我将不得不编辑几个函数,例如伪代码:
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);
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在编译时通过宏确保每个位置至少具有相同的参数计数?我想过制作dump_param某种宏来计算调用,然后添加类似的东西
#if nr_read != nr_dump
#error "You forgot something, idiot!"
#endif
Run Code Online (Sandbox Code Playgroud)
在模块的最后.我找不到一种让宏计算其调用的方法,尽管......
由于参数列表是两个功能相同,如何保理说出来,避免任何可能的不匹配?
#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
}
Run Code Online (Sandbox Code Playgroud)
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);
}
Run Code Online (Sandbox Code Playgroud)
offsetofstruct 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 i = 0; i < 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 i = 0; i < paramCount; ++i) {
Param *p = (Param*)((char*)config + allParams[i].config_offs);
dump_param(allParams[i].name, p);
}
}
Run Code Online (Sandbox Code Playgroud)