[英]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.