创建类似函数的宏

时间:2010-01-29 04:14:31

标签: c

gcc 4.4.2 c89

我有这个代码片段,我必须在很多代码中重复这些代码片段。我只是想知道有没有办法通过使用宏函数来缩短它?

我想改变代码。

ERR_INFO error_info; /* create error object */
ErrorInfo(&error_info); /* pass the address for it to be filled with error info */
fprintf(stderr, "And the error is? [ %s ]\n", error_info.msg); /* display the error msg */

我尝试创建一个宏函数来使用它。

#define DISPLAY_ERR(error_info) ErrorInfo(&error_info) error_info.msg
fprintf(stderr, "And the error is? [ %s ]\n", DISPLAY_ERR); /* display the error

任何建议都会有所帮助,

4 个答案:

答案 0 :(得分:6)

如果你真的想要一个宏:

#define DISPLAY_ERR(error_info) \
    do \
    { \
        ErrorInfo(&(error_info)); \
        fprintf(stderr, "And the error is? [ %s ]\n", (error_info).msg); \
    } while(0)

由于good reason,您需要do... while(0)

然后,当您要打印错误时调用宏:

if (error) {
    DISPLAY_ERR(error_info);
    /* more statements if needed */
}

我假设error_info已在某处定义。如果没有,或者如果你不想,那么你可以改变你的宏定义并使用:

#define DISPLAY_ERR() \
    do \
    { \
        ERR_INFO error_info;
        ErrorInfo(&error_info); \
        fprintf(stderr, "And the error is? [ %s ]\n", error_info.msg); \
    } while(0)

if (error) {
    DISPLAY_ERR();
    /* more statements if needed */
}

答案 1 :(得分:1)

您是否正在尝试创建一个“返回”值的宏?在C ++中,您可以使用逗号运算符,来计算左表达式,然后返回正确的表达式。你也可以用C语言做同样的事。

(foo(var), var.field) // foo(...)is evaluated first,
                      // then second expression is returned

DISPLAY(message) // Pass an argument to macro

答案 2 :(得分:1)

你需要让它像函数调用一样工作,因此它可以在函数调用的任何地方使用,除非没有返回值。您还需要用反斜杠标记中间线的末端。在这种情况下,'do { ... } while (0)成语非常有用:

#define DISPLAY_ERR() do { ERR_INFO error_info; ErrorInfo(&error_info); \
     fprintf(stderr, "And the error is? [ %s ]\n", error_info.msg); } while (0)

error_info变量是块的本地变量,因此您不必记住在使用宏的函数中声明它(或者将它作为文件静态或者,使思想消失,全局变量)。

请注意,此代码不返回值,但可以在函数中的任何位置使用void表达式:

if (somefunc() != 0)
    DISPLAY_ERR();
else if (anotherfunc() != 0)
    DISPLAY_ERR();
else
    do_something_useful_after_all();

我仍然希望确保使用常规函数测量开销,而不是使用类似函数的宏。经常使用,你可能仍然会有更好的功能。

答案 3 :(得分:1)

有几种方法可以做到这一点。您可以使用逗号运算符:

#define DISPLAY_ERR(error_info) (ErrorInfo(&(error_info)),(error_info).msg)

...或者您可以更改ErrorInfo()函数,使其返回值是您传递的指针:

#define DISPLAY_ERR(error_info) (ErrorInfo(&(error_info))->msg)

(以及其他一些选项)。