英文:
How to have a function argument as a parameter to a macro in C
问题
我想将一个函数作为参数传递给宏,从编译器错误消息来看,我做错了:
#define mu_run(func()) func() == 0 ? printf_green("测试通过:%s\n", #func()) : printf_red("测试失败:%s 在第%d行", #func(), mu_check())
我收到的错误是:“(”不得出现在宏参数列表中
#define mu_run(func()) func() == 0 ? printf_green("测试通过:%s\n", #func()) : printf_red("测试失败:%s 在第%d行", #func(), mu_check())
我不知道还应该怎么做,我尝试将其替换为没有括号的“func”,但我也不确定这是否正确。
英文:
I want to pass an argument that is a function into a macro, and it's obvious from compiler message errors I'm not doing it right:
#define mu_run(func()) func() == 0 ? printf_green("Test passed: %s\n", #func()) : printf_red("Test failed: %s at line %d", #func(), mu_check())
The error I get is: "(" may not appear in macro parameter list
#define mu_run(func()) func() == 0 ? printf_green("Test passed: %s\n", #func()) : printf_red("Test failed: %s at line %d", #func(), mu_check())
I don't know what else to do to it, I've tried replacing it with 'func' with no parenthesis, but I'm not sure if that's correct either.
答案1
得分: 4
预处理器在处理宏时,只是简单地替换标记 - 就像是将宏的声明中的文本复制粘贴到扩展中一样。
如果你想创建一个只调用给定函数的宏,你可以这样做:
#define call_function(x) x()
通过使用call_function(foo)来调用,将会扩展为foo()。
你不应该这样做:
#define call_function(x()) x()
括号()应该添加在扩展中(假设你想调用这个函数),而不是在声明中。
因此,你需要在宏的声明和扩展中都移除func后面的括号(当作字符串使用时):
#define mu_run(func) func() == 0 ? printf_green("Test passed: %s\n", #func) \
: printf_red("Test failed: %s at line %d", #func, mu_check())
正如评论中也提到的,你应该将整个扩展括在括号中,像这样:
#define mu_run(func) (func() == 0 ? printf_green("Test passed: %s\n", #func) \
: printf_red("Test failed: %s at line %d", #func, mu_check()))
这将保护你免受操作符优先级可能导致的问题,例如:
mu_run(func1) && mu_run(func2)
英文:
The pre-processor, when handling macros, just substitutes tokens - almost like a copy and paste of text from the declaration of the macro into the expansion.
If you wanted to make a macro that just calls a given function, you would have this:
#define call_function(x) x()
Invoking this with call_function(foo) would expand to foo().
You would not want:
#define call_function(x()) x()
The () are something you add in the expansion (assuming you want to call the function), not in the declaration.
So you need to remove the parentheses after func, both in the macro declaration, and its expansion (when used as a string):
#define mu_run(func) func() == 0 ? printf_green("Test passed: %s\n", #func) \
: printf_red("Test failed: %s at line %d", #func, mu_check())
As also noted in comments, you should enclose the entire expansion in parentheses, like so:
#define mu_run(func) (func() == 0 ? printf_green("Test passed: %s\n", #func) \
: printf_red("Test failed: %s at line %d", #func, mu_check()))
This will protect you from possible problems with operator precedence when you do something like:
mu_run(func1) && mu_run(func2)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论