跳至內容

可變參數巨集

本頁使用了標題或全文手工轉換
維基百科,自由的百科全書
「可變參數巨集」的各地常用名稱
中國大陸可變參數宏
臺灣可變參數巨集

可變參數巨集C語言C++語言函式巨集的參數個數可以是0個或多個。這一語言特性由C99引入。C++11也開始支援。[1]

聲明語法

[編輯]

聲明語法類似於可變參數函式:逗號後面三個句點"...",表示一個或多個參數。但常見編譯器也允許傳遞0個參數。[2][3]巨集擴充時使用特殊識別碼__VA_ARGS__表示所傳遞的參數的替換。

沒辦法訪問可變參數列內的單個參數,也不能獲知多少個參數被傳遞。[4]

實現支援

[編輯]

C/C++編譯器支援:

尾部逗號

[編輯]

對於可變參數為空情形,Visual Studio[3]直接去掉可變參數前面的逗號;GCC[2]需要在__VA_ARGS__前面放上##以去除逗號。

# define MYLOG(FormatLiteral, ...)  fprintf (stderr, "%s(%d): " FormatLiteral "\n", __FILE__, __LINE__, __VA_ARGS__)

對於

MYLOG("Too many balloons %u", 42);

擴充為:

fprintf (stderr, "%s(%u): " "Too many balloons %u" "\n", __FILE__, __LINE__, 42);

它等價於:

fprintf (stderr, "%s(%u): Too many balloons %u\n", __FILE__, __LINE__, 42);

但對於例子:

MYLOG("Attention!");

擴充為

fprintf (stderr, "%s(%u): " "Attention!" "\n", __FILE__, __LINE__, );

GCC將會編譯報錯.

GCC支援下述不可移植的擴充:

# define MYLOG(FormatLiteral, ...)  fprintf (stderr, "%s(%u): " FormatLiteral "\n", __FILE__, __LINE__, ##__VA_ARGS__)

這將刪除空的__VA_ARGS__尾部逗號。

參見

[編輯]

參考文獻

[編輯]
  1. ^ Working draft changes for C99 preprocessor synchronization – http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm頁面存檔備份,存於網際網路檔案館
  2. ^ 2.0 2.1 2.2 Variadic Macros – Using the GNU Compiler Collection (GCC). GNU Compiler Collection. [2017-04-01]. (原始內容存檔於2020-07-04). 
  3. ^ 3.0 3.1 3.2 Variadic Macros (C++). [2017-04-01]. (原始內容存檔於2016-06-11). 
  4. ^ Laurent Deniau. __VA_NARG__ - comp.std.c - Google Groups. groups.google.com. 2006-01-16. Usenet: [email protected]. (原始內容存檔於2012-11-07). 
  5. ^ Clang source code change that mentions __VA_ARGS__ support (2006-07-29), note that Clang was open-sourced in 2007. http://llvm.org/viewvc/llvm-project?view=revision&revision=38770[失效連結]
  6. ^ Sun Studio feature comparison – http://developers.sun.com/sunstudio/support/CCcompare.html頁面存檔備份,存於網際網路檔案館