簡體   English   中英

創建類似函數的宏

[英]Creating function-like macros

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

任何建議都是最有幫助的,

如果您真的想要一個宏:

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

由於充分的原因,您需要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 */
}

您是否要創建一個“返回”值的宏? 在C ++中,你可以用逗號,以評估左表達式,然后返回正確的表達。 您也可以在C中執行相同的操作。

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

DISPLAY(message) // Pass an argument to macro

您需要使其像函數調用一樣工作,因此可以在函數調用可以使用的任何地方使用它,除非不返回任何值。 您還需要用反斜杠標記中間行的末端。 在這種情況下,“ 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();

等等。

我仍然要確保我測量了使用常規函數與擁有類似函數的宏的開銷。 經常使用,使用真正的功能可能會更好。

您可以通過以下兩種方法進行操作。 您可以使用逗號運算符:

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

...或者您可以更改ErrorInfo()函數,使其返回值是您傳遞給它的指針:

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

(以及其他一些選項)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM