跳轉至內容

更多 C++ 慣用法/多語句宏

來自 Wikibooks,開放世界中的開放書籍

多語句宏

[編輯 | 編輯原始碼]

編寫多語句(多行)宏。

也稱為

[編輯 | 編輯原始碼]

有時將兩個或多個語句組合到一個宏中並像函式呼叫一樣呼叫它們會很有用。通常,行內函數應該是首選,但除錯宏等幾乎總是宏而不是函式呼叫。以一種天真的方式將多個語句組合到一個宏中可能會導致編譯錯誤,這些錯誤乍一看並不明顯。例如,

#define MACRO(X,Y) { statement1; statement2; }

如果在末尾附加分號,則在 if 語句中將失敗。

if (cond)
   MACRO(10,20); // Compiler error here because of the semi-colon.
else
   statement3;

上述語句展開為

if (cond)
   { statement1; statement2; }; // Compiler error here because of the semi-colon.
else
   statement3;

導致編譯錯誤。因此,人們想出了一個廣泛使用用於多語句宏的慣用法,它基於 do-while 迴圈。

解決方案和示例程式碼

[編輯 | 編輯原始碼]

這是一個多語句宏慣用法的示例。

#define MACRO(arg1, arg2) do {  \
  /* declarations, if any */    \
  statement1;                   \
  statement2;                   \
  /* ... */                     \
  } while(0)	/* (no trailing ; ) */

當呼叫者附加分號時,無論上下文如何,此擴充套件都成為單個語句。最佳化編譯器通常會刪除任何死測試,例如 while(0)。當宏用作函式呼叫的引數時,此慣用法沒有用。此外,此慣用法允許 return 語句。

func(MACRO(10,20)); // Syntax error here.

已知用途

[編輯 | 編輯原始碼]

自適應通訊環境 (ACE) 中的 ACE_NEW_RETURN、ACE_NEW_NORETURN 宏。

#define ACE_NEW_RETURN(POINTER,CONSTRUCTOR,RET_VAL) \
      do { POINTER = new (ACE_nothrow) CONSTRUCTOR; \
      if (POINTER == 0) { errno = ENOMEM; return RET_VAL; } \
    } while (0)
[編輯 | 編輯原始碼]

參考文獻

[編輯 | 編輯原始碼]
華夏公益教科書