2009-03-20 38 views
7

संभव डुप्लिकेट:
Problem compiling K&R exampleसूचक प्रकार मेल नहीं खाता चेतावनी

हाल ही में मैंने कश्मीर & द्वारा सी प्रोग्रामिंग भाषा के माध्यम से अपने रास्ते काम कर रहा है आर

धारा 5.11 में वे पॉइंटर्स को फ़ंक्शंस में शामिल करते हैं और उनके उदाहरण में टाइप करने के बाद - एक क्विकॉर्ट कार्यान्वयन जहां हम compari को पॉइंटर प्रदान करते हैं बेटा फ़ंक्शन जिसे हम उपयोग करना चाहते हैं - मुझे कंपाइलर से चेतावनी मिल रही है: सशर्त अभिव्यक्ति में पॉइंटर प्रकार मेल नहीं है।

उदाहरण है कि चेतावनी चलाता है से लाइन है (मेरे संकलक पर OS X 10.5.6 जीसीसी 4.0.1 है):

qsort((void **) lineptr, 0, nlines-1, 
     (int (*)(void*, void*))(numeric ? numcmp : strcmp)); 

कार्यक्रम segfaulting बिना निष्पादित करता है, लेकिन मैं हर चेतावनी smoosh चाहते मैं, या कम से कम उनके कारणों को समझ सकता हूं।

int numcmp(char *, char *); 

लेकिन मैनपेज के अनुसार, stcmp इस हस्ताक्षर है:

int strcmp(const char *s1, const char *s2); 

है क्योंकि थोड़ी भिन्न विधि हस्ताक्षर के सरल चेतावनी

numcmp के लिए समारोह घोषणा की तरह दिखता है? चेतावनी को अनदेखा करने के क्या परिणाम हैं?

+0

एडी ने एक डुप्ली के बारे में बताया। मैंने अपना खुद का सवाल बंद करने के लिए वोट दिया लेकिन मैंने सोचा कि एक तरीका होगा कि मालिक इसे संक्षेप में बंद कर सकता है। – Dana

+0

दाना, जांचें [के एंड आर उदाहरण संकलित करने में समस्या] (http://stackoverflow.com/questions/616906/problem-compiling-kr-example/616929) और आपको शायद आपके प्रश्न का उत्तर मिल जाएगा। अगर आप नहीं करते हैं तो हमें बताएं। – Eddie

उत्तर

1

यह कोशिश करने और निदान करने का एक तरीका यह है कि यदि आप अभिव्यक्ति को प्रतिस्थापित करते हैं तो क्या होता है?: दोनों में से केवल एक के साथ।

यदि यह केवल strcmp के लिए होता है और numcmp नहीं होता है, तो यह कॉन्स char * के कारण बहुत अच्छी तरह से हो सकता है। मुझे लगता है कि जबकि char * को हमेशा शून्य में परिवर्तित किया जा सकता है, आप कॉन्स्ट char * को शून्य * में "सुरक्षित रूप से" रूपांतरित नहीं कर सकते हैं।

यदि यह दोनों के साथ है, तो शायद यह फ़ंक्शन पॉइंटर्स के साथ कुछ समस्या है, जहां char * शून्य * में परिवर्तित हो गया है, लेकिन हस्ताक्षर समान होना चाहिए और वर्णों के बजाय voids होना एक समस्या है।

3

लघु जवाब: कश्मीर & आर सी नहीं पता था

लांग जवाब: वे इस तथ्य से विकलांग थे कि जब वे शुरू कर दिया, कोई नहीं जानता था सी, इसलिए वे इन सबसे छुटकारा पाना बना रहे थे के रूप में वे साथ गए

(थोड़ा) विस्तृत उत्तर के कम क्षुद्र प्रपत्र: भाषा विकसित किया गया है (कुछ कहेंगे बदल) काफ़ी के बाद से कश्मीर & आर लिखा गया था, लेकिन जब तक आप गतिशील उदाहरण के साथ ई बुक संस्करण मिला morphing, के & आर की आपकी प्रतिलिपि में उदाहरण "नए और अनुमोदित" ("अब और भी एएनएसआई!") भाषा के साथ नहीं रखा होगा।

7

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

यह उल्लेख नहीं करना चाहिए कि qsort के अंदर क्या हो रहा है विपरीत होगा: यानी, एक शून्य * numcmp में एक char * और स्ट्रैम्प में कॉन्स char * में डाला जाएगा।

और संकलक को इन मामलों में चेतावनी जारी करनी चाहिए। यदि आपको वास्तव में ऐसे फ़ंक्शन का उपयोग करना है जिसमें पैरामीटर के समान प्रकार नहीं हैं, तो शायद आपको एक रैपर फ़ंक्शन का उपयोग करना चाहिए जो कि प्रकार से मेल खाता है, और उसके बाद मूल फ़ंक्शन को कॉल करते समय उचित स्पष्ट कास्ट करता है।

उदाहरण के लिए:

static int strcmp_wrapper(void* s1, void* s2) { 
    return strcmp((char*)s1, (char*)s2); 
} 

static int numcmp_wrapper(void* n1, void* n2) { 
    return numcmp((char*)n1, (char*)n2); 
} 

qsort((void **) lineptr, 0, nlines-1, 
     (numeric ? numcmp_wrapper : strcmp_wrapper)); 

और qsort के लिए आधुनिक हस्ताक्षर

void 
qsort(void *base, size_t nel, size_t width, 
     int (*compar)(const void *, const void *)); 

है const के मुद्दे अपने प्रश्न में भूमिका निभाते हैं प्रतीत नहीं होता है, लेकिन कश्मीर & आर नहीं था const है।

+0

एक और विकल्प निम्नलिखित में टर्नरी अभिव्यक्ति को बदलना है: संख्यात्मक? (int (*) (शून्य *, शून्य *)) numcmp: (int (*) (शून्य *, शून्य *)) strcmp); तो बस qsort को अलग-अलग दो अलग-अलग फ़ंक्शन पास कर दें। यह संकलक द्वारा दी गई किसी भी चेतावनी से भी बच जाएगा – bryanph