英文:
C preprocessor: redefine macro, macro overload
问题
以下是您要翻译的内容:
以下代码有一个由FLAG控制的宏,用于在编译时使用func1或func2。我想通过使用“FLAG”宏(定义/取消定义)在main()上执行的方式来使其在编译时在这两个函数之间切换。这只是一个示例,用法将跨多个文件。
我的问题是,这只执行func1(),因为预处理器已将符号分配给func_wrapper,而我没有更改它。另外,如果我执行#undef func_wrapper
,就需要通过添加更多代码来重新定义它。
我的问题是,是否可以在不每次重新定义func_wrapper的情况下实现这一点。就像是在未定义FLAG时,预处理器再次经过宏并重新检查已定义的内容一样。
我希望得到类似以下代码的结果:
#include "functions.h"
#include "functions2.h"
#define FLAG
#ifdef FLAG
#define func_wrapper func1
#endif
#ifndef FLAG
#define func_wrapper func2
#endif
int main(){
func_wrapper();
#undef FLAG
func_wrapper();
}
并且运行结果与以下类似:
...
//与之前相同
...
int main(){
func_wrapper();
#undef FLAG
#ifndef FLAG
#undef func_wrapper
#define func_wrapper func2
#endif
func_wrapper();
}
英文:
The following code has a FLAG controlled macro to use func1 or func2 when compiling. I want to make it switch between the 2 function when compiling by using the "FLAG" macro (defining/undefining) as it's done on main(). This is just a sample/example, the usage will be across multiple files.
My question is that this only executes func1() as the preprocessor have assigned the symbol to func_wrapper and I'm not changing it. Also if if do #undef func_wrapper
it will be required to redefine it by adding more code.
My question is if it is possible to achieve that without having the redefine of func_wrapper each time. It something like making the preprocessor do another pass over the macros when the FLAG is undefined and check again the defines that where defined under.
I want to get something that looks like the following code:
#include "functions.h"
#include "functions2.h"
#define FLAG
#ifdef FLAG
#define func_wrapper func1
#endif
#ifndef FLAG
#define func_wrapper func2
#endif
int main(){
func_wrapper();
#undef FLAG
func_wrapper();
}
and runs like the follwing one:
...
//same as previous one
...
int main(){
func_wrapper();
#undef FLAG
#ifndef FLAG
#undef func_wrapper
#define func_wrapper func2
#endif
func_wrapper();
}
答案1
得分: 3
if it is possible to achieve that without having the redefine of func_wrapper each time
不行。
making the preprocessor do another pass over the macros
你必须手动输入另一个遍历。
#include "functions.h"
#include "functions2.h"
#define FLAG
#ifdef FLAG
#define func_wrapper func1
#else
#define func_wrapper func2
#endif
int main() {
func_wrapper();
#undef FLAG
#undef func_wrapper
#ifdef FLAG
#define func_wrapper func1
#else
#define func_wrapper func2
#endif
func_wrapper();
}
你可以把这部分放在一个头文件中。
// resolve_flag.h
#ifdef func_wrapper
#undef func_wrapper
#endif
#ifdef FLAG
#define func_wrapper func1
#else
#define func_wrapper func2
#endif
// main.h
#include "functions.h"
#include "functions2.h"
#define FLAG
#include "resolve_flag.h"
int main() {
func_wrapper();
#undef FLAG
#include "resolve_flag.h"
func_wrapper();
}
但也许可以使用运行时和一些全局状态来实现:
bool flag = 0;
void func_wrapper(void) {
flag ? func1() : func2();
}
int main() {
func_wrapper();
flag = 1;
func_wrapper();
}
英文:
> if it is possible to achieve that without having the redefine of func_wrapper each time
No.
> making the preprocessor do another pass over the macros
You have to type out that another pass.
#include "functions.h"
#include "functions2.h"
#define FLAG
#ifdef FLAG
#define func_wrapper func1
#else
#define func_wrapper func2
#endif
int main() {
func_wrapper();
#undef FLAG
#undef func_wrapper
#ifdef FLAG
#define func_wrapper func1
#else
#define func_wrapper func2
#endif
func_wrapper();
}
You can put that in a header.
// resolve_flag.h
#ifdef func_wrapper
#undef func_wrapper
#endif
#ifdef FLAG
#define func_wrapper func1
#else
#define func_wrapper func2
#endif
// main.h
#include "functions.h"
#include "functions2.h"
#define FLAG
#include "resolve_flag.h"
int main() {
func_wrapper();
#undef FLAG
#include "resolve_flag.h"
func_wrapper();
}
But maybe just use runtime and some global state:
bool flag = 0;
void func_wrapper(void) {
flag ? func1() : func2();
}
int main() {
func_wrapper();
flag = 1;
func_wrapper();
}
答案2
得分: 1
Here's the translated content from your provided text:
如果 func_wrapper
最初不是宏,您可以重新定义它为其他内容,只需一行源代码:
#include "functions.h"
#include "functions2.h"
// 默认定义。我们可以使用宏让某些调用者直接调用func2
static inline void func_wrapper() {
func1();
}
// #define func_wrapper func2
int main()
{
func_wrapper(); // 调用func1
#define func_wrapper func2
func_wrapper(); // 调用func2
#undef func_wrapper // 现在它又成为func1的别名
}
这相当丑陋,看起来相当巧妙,而且失去了FLAG的单独名称,这个名称可能具有一些有用的语义意义。我不建议这样做。
如果函数实际上需要参数,您的包装器必须将它们传递下去。
您实际上不需要CPP,如果可以使用嵌套函数,这是GNU C的扩展。这在GCC中可以工作,但在clang中不行(Godbolt)。
// 默认定义
static inline void func_wrapper() {
func1();
}
int main()
{
func_wrapper();
static inline void func_wrapper(){ func2(); } // 遮蔽了全局定义
func_wrapper();
}
这甚至更糟,因为包装器的定义会使您在其中使用它的函数变得混乱。
英文:
If func_wrapper
is not originally a macro, you can redefine it to something else with only one line of source:
#include "functions.h"
#include "functions2.h"
// default definition. We can use macros to have some callers call func2 directly
static inline void func_wrapper() {
func1();
}
// #define func_wrapper func2
int main()
{
func_wrapper(); // call func1
#define func_wrapper func2
func_wrapper(); // call func2
#undef func_wrapper // now it's back to an alias for func1
}
This is rather ugly and seems pretty hacky, and loses the separate name of FLAG which presumably has some useful semantic meaning. I wouldn't recommend doing this.
If the function actually takes args, your wrapper would have to pass them on.
You actually don't need CPP at all if you can use nested functions, a GNU C extension. This works in GCC but not clang (Godbolt).
// default definition
static inline void func_wrapper() {
func1();
}
int main()
{
func_wrapper();
static inline void func_wrapper(){ func2(); } // shadows the global definition
func_wrapper();
}
This is even worse, since the wrapper definition clutters up the function you're using it inside.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论