C99 में वेरिएडिक मैक्रो के लिए खाली आर्गों के साथ एक अच्छी तरह से ज्ञात समस्या है ।
उदाहरण:
#define FOO(...) printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)
FOO("this works fine");
BAR("this breaks!");
BAR()
उपरोक्त का उपयोग वास्तव में C99 मानक के अनुसार गलत है, क्योंकि यह इसका विस्तार करेगा:
printf("this breaks!",);
ध्यान रखें अल्पविराम - व्यावहारिक नहीं है।
कुछ संकलक (जैसे: विजुअल स्टूडियो 2010) चुपचाप आपके लिए उस अनुगामी अल्पविराम से छुटकारा दिलाएगा। अन्य संकलक (जैसे: GCC) समर्थन ##
सामने रख रहे हैं __VA_ARGS__
, जैसे:
#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)
लेकिन क्या इस व्यवहार को प्राप्त करने के लिए एक मानक-अनुपालन तरीका है? शायद कई मैक्रोज़ का उपयोग करना?
अभी, ##
संस्करण काफी अच्छी तरह से समर्थित (कम से कम मेरे प्लेटफार्मों पर) लगता है, लेकिन मैं वास्तव में मानकों के अनुरूप समाधान का उपयोग करूंगा।
पूर्व-खाली: मुझे पता है कि मैं सिर्फ एक छोटा कार्य लिख सकता हूं। मैं मैक्रो का उपयोग करके ऐसा करने की कोशिश कर रहा हूं।
संपादित करें : यहां एक उदाहरण (हालांकि सरल) है कि मैं बार () का उपयोग क्यों करना चाहता हूं:
#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);
यह स्वचालित रूप से मेरे BAR () लॉगिंग स्टेटमेंट में एक नई पंक्ति जोड़ता है, यह मानते हुए कि fmt
यह हमेशा डबल-उद्धृत सी-स्ट्रिंग है। यह न्यूलाइन को एक अलग प्रिंटफ () के रूप में मुद्रित नहीं करता है, जो लॉग-लाइन बफ़र किया गया है और कई स्रोतों से अतुल्यकालिक रूप से आ रहा है, तो यह फायदेमंद है।
__VA_OPT__
कीवर्ड के आधार पर एक नए वाक्यविन्यास का उपयोग करता है । यह पहले से ही सी ++ द्वारा "अपनाया गया" है, इसलिए मुझे उम्मीद है कि सी सूट का पालन करेगा। (पता नहीं है कि इसका मतलब है कि यह C ++ 17 में तेजी से ट्रैक किया गया था या अगर यह C ++ 20 के लिए सेट किया गया है)
BAR
बजाय क्यों उपयोग करेंFOO
?