2009-06-15 12 views
13

यहां कोड का एक छोटा टुकड़ा है:जीसीसी विशेषता 'प्रारूप' का उपयोग कैसे करें?

#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 पर कॉल करें):

बहुत कम प्रारूप

  1. के लिए तर्क क्या मैंने यह सही किया?
  2. मैंने देखा कि MyPrintf घोषणा पर, यदि मैं विशेषता भाग को हटा देता हूं, तो मुझे अभी भी लाइन 22 पर वांछित चेतावनी मिल जाएगी। मैंने यह भी देखा कि इस विशेषता भाग में, सूचकांक को 1 से 2 में बदलना कोई भी नहीं देगा चेतावनी या त्रुटि। कौन सा सही है और इस समारोह पर विशेषता का लक्ष्य क्या है?
  3. यदि मैं निम्न फ़ंक्शन 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 में हैं ("प्रारूप (आर्केटाइप, स्ट्रिंग-इंडेक्स, प्रथम-से-चेक)" के लिए देखें)।

धन्यवाद।

उत्तर

10

प्रलेखन में आपको आवश्यक उत्तर है।विशेष रूप से:

  1. हाँ
  2. एक आपने पोस्ट किया है सही (format(printf, 1, 0)) है। 1 क्योंकि प्रारूप स्ट्रिंग पैरामीटर 1, 0 है क्योंकि चेक किए जाने के लिए कोई भिन्न तर्क नहीं हैं।
+1

MyVariadicPrintf में, मैं समझता हूं कि संकलक स्थिति 1 पर स्ट्रिंग के खिलाफ स्थिति 2 से शुरू होने वाले तर्कों की संख्या और प्रकारों की जांच करेगा। लेकिन MyPrintf के मामले में, कंपाइलर चेक क्या करता है? – Guillaume

+1

MyPrintf के मामले में, यह केवल प्रारूप स्ट्रिंग की वैधता की जांच करेगा (उदाहरण के लिए कि यह "% _%" जैसा कुछ नहीं है) – jpalecek

+0

ठीक है, बहुत बहुत धन्यवाद! – Guillaume

3

GCC docs on gnu.org पर एक नज़र डालें। आखिरी सवाल के लिए, मेरा अनुमान है कि MyPrintf टेम्पलेट फ़ंक्शन नहीं है और केवल एक ही परिभाषा उपलब्ध है जो पहले तर्क के रूप में char const* लेती है, इसलिए यह सुझाव देने में सुरक्षित महसूस करता है।

संबंधित मुद्दे