यहां कोड का एक छोटा टुकड़ा है:जीसीसी विशेषता 'प्रारूप' का उपयोग कैसे करें?
#include <stdio.h>
#include <stdarg.h>
void MyPrintf(char const* format, va_list args);
void MyVariadicPrintf(char const* format, ...);
void MyPrintf(char const* format, va_list args)
{
vprintf(format, args);
}
void MyVariadicPrintf(char const* format, ...)
{
va_list args;
va_start(args, format);
MyPrintf(format, args);
va_end(args);
}
int main(int, char*)
{
MyVariadicPrintf("%s" /* missing 2nd argument */);
return 0;
}
मैं इसे जीसीसी 4.0 के साथ संकलित कर रहा हूं, मैक ओएस एक्स तेंदुए पर एक्सकोड चला रहा हूं।
-Wformat और -missing-format-विशेषता सक्षम हैं।
यह कोड लाइन 9 (vprintf
पर कॉल करें) पर एक चेतावनी देता है, यह बताता है कि MyPrintf
'प्रारूप' विशेषता का उपयोग कर सकता है:
फ़ंक्शन 'printf' प्रारूप विशेषता के लिए संभावित उम्मीदवार हो सकता है
इसलिए मैं इस तरह की विशेषता जोड़ता हूं (सुनिश्चित नहीं है कि यह सही है):
void MyPrintf(char const* format, va_list args) __attribute__((format(printf, 1, 0)));
पिछली चेतावनी गायब हो जाती है और एक ही चेतावनी अब लाइन 16 (MyPrintf
पर कॉल करें) पर दिखाई देती है, यह बताती है कि MyVariadicPrintf
'प्रारूप का उपयोग कर सकता है 'विशेषता।
इसलिए मैं इस तरह की विशेषता जोड़ता हूं (यकीन है कि यह इस समय सही है):
void MyVariadicPrintf(char const* format, ...) __attribute__((format(printf, 1, 2)));
और अब मुझे लाइन 22 पर अपेक्षित चेतावनी मिलती है (MyVariadicPrintf
पर कॉल करें):
बहुत कम प्रारूप
- के लिए तर्क क्या मैंने यह सही किया?
- मैंने देखा कि
MyPrintf
घोषणा पर, यदि मैं विशेषता भाग को हटा देता हूं, तो मुझे अभी भी लाइन 22 पर वांछित चेतावनी मिल जाएगी। मैंने यह भी देखा कि इस विशेषता भाग में, सूचकांक को 1 से 2 में बदलना कोई भी नहीं देगा चेतावनी या त्रुटि। कौन सा सही है और इस समारोह पर विशेषता का लक्ष्य क्या है? यदि मैं निम्न फ़ंक्शन
MyVariadicPrintfT
जोड़ता हूं और इसे कॉल करता हूं (char
के साथ विशिष्ट), तो मुझे इस फ़ंक्शन पर 'प्रारूप' विशेषता का उपयोग करने का सुझाव देने वाली चेतावनी मिल जाएगी। मुझे लगता है कि यह असंभव है क्योंकिformat
तर्क templated प्रकार पर निर्भर है। क्या मैं सही हू?template<typename Type> void MyVariadicPrintfT(Type const* format, ...) { va_list args; va_start(args, format); MyPrintf(format, args); va_end(args); }
नवीनतम gnu दस्तावेज gnu.org पर पाया जा सकता है।
चेतावनी विकल्प section 3.8 में हैं ("WMissing-format-विशेषता" के लिए देखें)।
फ़ंक्शन विशेषताएँ section 6.30 में हैं ("प्रारूप (आर्केटाइप, स्ट्रिंग-इंडेक्स, प्रथम-से-चेक)" के लिए देखें)।
धन्यवाद।
MyVariadicPrintf में, मैं समझता हूं कि संकलक स्थिति 1 पर स्ट्रिंग के खिलाफ स्थिति 2 से शुरू होने वाले तर्कों की संख्या और प्रकारों की जांच करेगा। लेकिन MyPrintf के मामले में, कंपाइलर चेक क्या करता है? – Guillaume
MyPrintf के मामले में, यह केवल प्रारूप स्ट्रिंग की वैधता की जांच करेगा (उदाहरण के लिए कि यह "% _%" जैसा कुछ नहीं है) – jpalecek
ठीक है, बहुत बहुत धन्यवाद! – Guillaume