C99中可變參數(shù)宏的空參數(shù)存在一個(gè)眾所周知的 問題。例:#define FOO(...) printf(__VA_ARGS__)#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)FOO("this works fine");BAR("this breaks!");BAR()根據(jù)C99標(biāo)準(zhǔn),上面的使用確實(shí)是不正確的,因?yàn)樗鼘U(kuò)展為:printf("this breaks!",);請(qǐng)注意結(jié)尾的逗號(hào)-不可行。一些編譯器(例如:Visual Studio 2010)將悄悄地為您消除尾隨的逗號(hào)。其他編譯器(例如:GCC)也支持放在##前面__VA_ARGS__,例如:#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)但是,是否存在符合標(biāo)準(zhǔn)的方法來實(shí)現(xiàn)此行為?也許使用多個(gè)宏?現(xiàn)在,該##版本似乎受到了很好的支持(至少在我的平臺(tái)上),但是我確實(shí)希望使用符合標(biāo)準(zhǔn)的解決方案。先發(fā)制人:我知道我可以編寫一個(gè)小函數(shù)。我正在嘗試使用宏。編輯:這是為什么我想使用BAR()的示例(盡管很簡單):#define BAR(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)BAR("here is a log message");BAR("here is a log message with a param: %d", 42);假定fmt始終是雙引號(hào)的C字符串,這會(huì)自動(dòng)向我的BAR()記錄語句添加換行符。它不會(huì)將換行符作為單獨(dú)的printf()打印,如果日志記錄是行緩沖的并且異步地來自多個(gè)源,則這是有利的。
3 回答

繁星coding
TA貢獻(xiàn)1797條經(jīng)驗(yàn) 獲得超4個(gè)贊
這不是一個(gè)通用的解決方案,但是對(duì)于printf,您可以添加一個(gè)換行符,例如:
#define BAR_HELPER(fmt, ...) printf(fmt "\n%s", __VA_ARGS__)
#define BAR(...) BAR_HELPER(__VA_ARGS__, "")
我相信它會(huì)忽略格式字符串中未引用的任何其他參數(shù)。因此,您甚至可以擺脫:
#define BAR_HELPER(fmt, ...) printf(fmt "\n", __VA_ARGS__)
#define BAR(...) BAR_HELPER(__VA_ARGS__, 0)
我不敢相信沒有標(biāo)準(zhǔn)方法即可批準(zhǔn)C99。AFAICT該問題也存在于C ++ 11中。
- 3 回答
- 0 關(guān)注
- 2178 瀏覽
添加回答
舉報(bào)
0/150
提交
取消