可變參數巨集
可變參數巨集是C語言與C++語言的函數巨集的參數個數可以是0個或多個。這一語言特性由C99引入。C++11也開始支援。[1]
「可變參數巨集」的各地常用名稱 | |
---|---|
中國大陸 | 可變參數宏 |
臺灣 | 可變參數巨集 |
聲明語法
編輯聲明語法類似於可變參數函數:逗號後面三個句點"...",表示一個或多個參數。但常見編譯器也允許傳遞0個參數。[2][3]巨集擴充時使用特殊識別碼__VA_ARGS__表示所傳遞的參數的替換。
沒辦法訪問可變參數列內的單個參數,也不能獲知多少個參數被傳遞。[4]
實現支援
編輯C/C++編譯器支援:
- GNU Compiler Collection 3.0,[2]
- Clang ,[5]
- Visual Studio 2005,[3]
- C++Builder 2006,
- Oracle Solaris Studio (Sun Studio) Forte Developer 6 update 2 (C++ version 5.3).[6]
尾部逗號
編輯對於可變參數為空情形,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__尾部逗號。
參見
編輯參考文獻
編輯- ^ Working draft changes for C99 preprocessor synchronization – http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1653.htm (頁面存檔備份,存於互聯網檔案館)
- ^ 2.0 2.1 2.2 Variadic Macros – Using the GNU Compiler Collection (GCC). GNU Compiler Collection. [2017-04-01]. (原始內容存檔於2020-07-04).
- ^ 3.0 3.1 3.2 Variadic Macros (C++). [2017-04-01]. (原始內容存檔於2016-06-11).
- ^ Laurent Deniau. __VA_NARG__ - comp.std.c - Google Groups. groups.google.com. 2006-01-16. Usenet: dqgm2f$ije$1@sunnews.cern.ch. (原始內容存檔於2012-11-07).
- ^ 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[失效連結]
- ^ Sun Studio feature comparison – http://developers.sun.com/sunstudio/support/CCcompare.html (頁面存檔備份,存於互聯網檔案館)