我正在尝试检测一些代码来捕获和打印错误消息。目前我正在使用像这样的宏:
#define my_function(x) \
switch(function(x)) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
}
通常,我从不捕获函数输出,这很好用。但我发现了一些情况,我还需要function()
的返回值。我试过类似下面的内容,但这会产生语法错误。
#define my_function(x) \
do { \
int __err = function(x); \
switch(__err) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
} \
__err; \
} while(0)
我可以声明一个全局变量来保存函数的返回值,但这看起来很难看,我的程序是多线程的,所以这可能会导致问题。我希望那里有更好的解决方案。
答案 0 :(得分:46)
GCC有一个名为statement expressions
的功能所以如果像
那样定义宏#define FOO(A) ({int retval; retval = do_something(A); retval;})
您可以像
一样使用foo = FOO(bar);
答案 1 :(得分:6)
这是相对复杂的代码,没有太多理由在宏中使用它。如果您确实要将其放在头文件中,请将其设为inline
(C99)或static
(C89)或两者。使用任何合理的编译器,这应该导致与宏相同的效率。
答案 2 :(得分:4)
回复非常晚。但也是如此。我同意内联函数更好,但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; \
})
答案 3 :(得分:2)
抱歉,这是一个编辑...
像这样:
#define my_function(x, out) \
{ \
int __err = function(x); \
switch(__err) { \
case ERROR: \
fprintf(stderr, "Error!\n"); \
break; \
} \
__err; \
(*(out)) = _err; \
}
要保留传递引用C范例,您应该以这种方式调用my_function:
int output_err;
my_function(num, &output_err);
这样,稍后,如果您决定使my_function成为一个真正的函数,则无需更改调用引用。
顺便说一句,qrdl的“声明表达”也是一种很好的方法。
答案 4 :(得分:-2)
如果函数返回某些内容,则无需声明变量,那么您可以直接获取该值。例如:
#define FOO(A) do_something(A)
这里do_something返回一些整数。然后你可以轻松地使用它:
int a = FOO(a);