如何将函数参数作为C中宏的参数传递

huangapple go评论79阅读模式
英文:

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)

huangapple
  • 本文由 发表于 2023年6月29日 05:38:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76576869.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定