C语言 在 C 宏中使用和返回输出
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3532621/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using and returning output in C macro
提问by Michael Mior
I'm trying to instrument some code to catch and print error messages. Currently I'm using a macro somethng like this:
我正在尝试编写一些代码来捕获和打印错误消息。目前我正在使用这样的宏:
#define my_function(x) \
switch(function(x)) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
}
Normally, I never capture the function output and this works fine. But I've found a couple cases where I also need the return value of function(). I tried something like the following, but this produces a syntax error.
通常,我从不捕获函数输出,这很好用。但是我发现了一些情况,我还需要function(). 我尝试了类似以下的内容,但这会产生语法错误。
#define my_function(x) \
do { \
int __err = function(x); \
switch(__err) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
} \
__err; \
} while(0)
I could declare a global variable to hold the return value of the function, but that looks ugly and my program is multithreaded, so that's likely to cause problems. I'm hoping there's a better solution out there.
我可以声明一个全局变量来保存函数的返回值,但这看起来很难看,而且我的程序是多线程的,所以这可能会导致问题。我希望那里有更好的解决方案。
采纳答案by Jens Gustedt
This is relatively complicated code, there is not much reason to have it in a macro. Make it inline(C99) or static(C89) or both if you really want to place it in a header file. With any reasonable compiler this then should result in the same efficiency as a macro.
这是相对复杂的代码,没有太多理由将它放在宏中。如果您真的想将它放在头文件中,请使用inline(C99) 或static(C89) 或两者兼而有之。使用任何合理的编译器,这应该导致与宏相同的效率。
回答by qrdl
GCC has a feature called statement expressions
GCC 有一个特性叫做语句表达式
So if define macro like
所以如果像这样定义宏
#define FOO(A) ({int retval; retval = do_something(A); retval;})
then you will be able to use it like
然后你就可以像这样使用它
foo = FOO(bar);
回答by simp76
A very late reply. But none the less. I agree inline functions are better but MACROs do offer some pretty printing fun you can't get with inline functions. I agree with @qrdl that you can indeed use statement expressions had you restructured your statements a bit. Here is how it would work with a macro -
一个很晚的答复。但无论如何。我同意内联函数更好,但宏确实提供了一些内联函数无法获得的漂亮打印乐趣。我同意@qrdl 的观点,如果您稍微调整一下语句的结构,您确实可以使用语句表达式。这是它如何与宏一起工作 -
#define my_function(x, y) ({ \
int __err = 0; \
do { \
__err = function(x, y); \
switch(__err) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
} \
} while(0); \
__err; \
})
回答by hopia
Sorry, this is an edit...
对不起,这是一个编辑...
- I think you just need the curly braces. No need for the do..while keywords
- Make sure that the backslashes are the last characters on each line (no space after).
- If you need to get the err value out of the macro, you can just add a parameter
- 我认为你只需要花括号。不需要 do..while 关键字
- 确保反斜杠是每行的最后一个字符(后面没有空格)。
- 如果您需要从宏中获取 err 值,只需添加一个参数即可
Like so:
像这样:
#define my_function(x, out) \
{ \
int __err = function(x); \
switch(__err) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
} \
__err; \
(*(out)) = _err; \
}
To preserve the pass-by-reference C paradigm, you should call my_function this way:
为了保留传递引用 C 范式,您应该这样调用 my_function:
int output_err;
my_function(num, &output_err);
This way, later, if you decide to make my_function a real function, you don't need to change the call references.
这样,以后,如果您决定使 my_function 成为真正的函数,则无需更改调用引用。
Btw, qrdl's "Statement Expressions" is also a good way to do it.
顺便说一句,qrdl 的“语句表达式”也是一个很好的方法。
回答by The joker
there is no need to declare variable if your function is returning something then you can directly get that value. For example:
如果您的函数正在返回某些内容,则无需声明变量,那么您可以直接获取该值。例如:
#define FOO(A) do_something(A)
Here do_something returns some integer. Then you can easily use it like:
这里 do_something 返回一些整数。然后您可以轻松地使用它,例如:
int a = FOO(a);

