2012-03-29 23 views
16

मैंने इस पर जानकारी के लिए थोड़ी सी खोज की लेकिन मुझे कुछ भी संतोषजनक नहीं मिला। क्या फंक्शन कॉलजीसीसी -Wall शून्य-लंबाई प्रारूप स्ट्रिंग के बारे में चेतावनी क्यों देता है?

sprintf(someString, ""); 

में कुछ विशेष व्यवहार है जो बताता है कि यह चेतावनी क्यों है (gcc पर -Wall पर)? मैं केवल यह पाया कि सी मानक शून्य-लंबाई प्रारूप तारों की अनुमति देता है।

मैं निम्न उदाहरण

#include <stdio.h> 

int main() 
{ 
    char str[2] = {'a', 'a'}; 
    sprintf(str, ""); 
    printf("\'%c\'\'%c\'\n", str[0], str[1]); 
    return 0; 
} 

जो

'''a' 

बाहर प्रिंट जो वास्तव में क्या मैं देख रहा हूँ के लिए उम्मीद की कोशिश की। तो, चेतावनी क्यों?

+2

मुझे यह नहीं मिलता है कि आपको यह कहां मिल गया है कि C++ नहीं है ... –

+1

आप सही हैं, मैंने सोचा था कि यह पहली बार था क्योंकि मैं g ++ के साथ कोड संकलित कर रहा था, लेकिन अब मुझे लगता है कि जीसीसी देता है एक ही चेतावनी। – SirGuy

+0

ओह, और यदि कोई सोच रहा है, तो मैंने गलती से इस कोड में ठोकर खाई, मैंने वास्तव में इसे खुद को – SirGuy

उत्तर

22

तथ्य यह है कि जीसीसी एक चेतावनी जारी करता है आम तौर पर यह नहीं है कि निर्माण कानूनी सी है या नहीं, लेकिन क्या जीसीसी डेवलपर्स इसे या तो संभावित संकेत मानते हैं कि आप जो कुछ लिखते हैं, या सिर्फ खराब शैली के अलावा कुछ और मतलब है। - आप लगभग निश्चित रूप से मतलब if (x == 0)

  • if (x = 0): यहाँ कुछ उदाहरण हैं।
  • printf(str) - आप लगभग निश्चित रूप से fputs(str, stdout) या printf("%s", str) का मतलब था; लिखित के रूप में, कोड बहुत खतरनाक है।
  • if (foo == bar & MASK) - आप लगभग निश्चित रूप से if (foo == (bar & MASK)) का मतलब था।

आदि

आपके मामले में, मुझे लगता है कि जीसीसी तुम क्यों String[0]=0; के बराबर करने के लिए sprintf(String, "") कॉल कर रहे हैं पूछताछ कर रहा है (उत्तरार्द्ध बहुत कम है, तेज, और स्पष्ट)।

+1

मैं मानता हूं कि बेहतर होगा, मुझे नहीं पता कि इससे एक चेतावनी पर विचार करने के लिए उससे अधिक कारण है या नहीं। मैं निश्चित रूप से कोई अधिकार नहीं हूं लेकिन मुझे नहीं लगता था कि उचित प्रोग्रामिंग के लिए यह विशेष अपराध चेतावनी-योग्य – SirGuy

+3

माना जाएगा, लेकिन जीसीसी चेतावनी के साथ बहुत अधिक परेशान चीजें करता है। यह निश्चित रूप से एक कम अपराध है।एक बड़ा व्यक्ति अप्रयुक्त फ़ंक्शन तर्कों पर चेतावनियां दे रहा है, जो * अपरिहार्य * है जब भी आप फ़ंक्शन पॉइंटर्स का उपयोग कर रहे हैं जो किसी विशेष हस्ताक्षर के अनुरूप होना चाहिए। –

+0

हू, मैंने कभी उस चेतावनी को पहले कभी नहीं देखा है, और मुझे यह स्थिति मिली है – SirGuy

4

यह बस जीसीसी द्वारा चेतावनी है। आप अपने आवेदन के एक भाग के लिए यह दबाने के लिए चाहते हैं, तो आप निम्न कर सकते हैं:

#pragma GCC diagnostic ignored "-Wformat-zero-length" 
int main() 
{ 
    // code that produces a warning 
} 
#pragma GCC diagnostic warning "-Wformat-zero-length" 
+1

मुझे पता है कि मैं इससे छुटकारा पा सकता हूं, मैं सोच रहा था कि यह – SirGuy

+5

से शुरू करने के लिए क्यों था, मुझे लगता है कि यह सिर्फ एक गैरकानूनी, हानिकारक चेतावनी है। यह निश्चित रूप से कोड काट सकता है जहां प्रारूप स्ट्रिंग या तो प्रीप्रोसेसर मैक्रो की परिभाषा/मान के आधार पर शून्य लंबाई या नॉनट्रिविअल है, और ऐसा कोड पूरी तरह से उचित लगता है। –

+3

यह _not_ हानिकारक है। यह सिर्फ आपको बता रहा है कि आपके कोड के बारे में कुछ संदिग्ध है, कि आपने _might_ को गलती की है। यद्यपि 'sprintf (str," ");' कानूनी है, यह _str_ शून्य-लंबाई वाली स्ट्रिंग बनाने का एक गोल तरीका है, और आपके कोड में तार्किक त्रुटि इंगित कर सकता है। यह मना नहीं है; बस आपके ध्यान में लाया। –

6

क्योंकि जीसीसी जानता है कि sprintf() को दूसरा तर्क एक गैर खाली स्ट्रिंग होना चाहिए, आम तौर पर आप चेतावनी हो रही है एक विभिन्न प्रारूप विनिर्देशों के साथ - आपके कोड में जो काम कर रहा है उसके लिए एक कार्यात्मक रूप से समकक्ष और "अधिक कानूनी" कॉल sprintf(str, "%s", "") होगा। साथ ही, प्रारूप विनिर्देशों को पूरा करने के लिए पर्याप्त रूप से एन अतिरिक्त तर्कों में से लगभग हमेशा एक होता है। जैसा कि आप इसे यहां उपयोग कर रहे हैं, आप इसे strcpy() के रूप में उपयोग कर रहे हैं, जो तकनीकी रूप से मान्य है, मानक लाइब्रेरी का उपयोग करने का एक बहुत ही अजीब तरीका है।