2010-02-18 14 views
5

बिना पुराने स्टाइल कार्यों के साथ एक सी संकलक का व्यवहार मेरे कार्यक्रम दो फ़ाइलों के होते हैं जब कोई त्रुटि नहीं दिखाओ।प्रोटोटाइप

मेरा कार्यक्रम केवल एक फ़ाइल के होते हैं जब:

main.c

#include <stdio.h> 

int main(void) { 
    printf("%lf\n",f()); 
    return 0; 
} 

double f(int a) { 
return 1; 
} 

दृश्य C++ 2008 संकलक निम्न त्रुटि दिखाने:

Error 2 error C2371: 'f' : redefinition; different basic types d:\temp\projects\function1\function1\1.c 8 function1 

किसी को भी यह अजीब व्यवहार की व्याख्या कर सकते हैं?

+0

जैसा कि मैं समझता हूं: पहले मामले में लिंकर फ़ंक्शन को कॉल की परिभाषा के साथ बाध्य करने के लिए ज़िम्मेदार है; दूसरे मामले में संकलक फ़ंक्शन को कॉल की परिभाषा के साथ बाध्य करने के लिए ज़िम्मेदार है। क्या मैं सही हूँ? –

उत्तर

5

दोनों कार्यक्रम गलत हैं।

दायरे में प्रोटोटाइप के बिना, एक कंपाइलर मानता है कि एक समारोह int देता है और पैरामीटर की एक निर्दिष्ट संख्या लेता है।

के लिए अपनी फ़ाइलें थोड़ा बदल डालते हैं: (चाहिए भी, अनुरूप मोड में विजुअल C++)

$ cat func.c 
double f(int a) { 
    return 1.0; 
} 
$ cat main.c 
#include <stdio.h> 

int main(void) { 
    double d = f(); 
    printf("%lf\n", d); 
    return 0; 
} 

जब मैं यह संकलन, जीसीसी मुझे चेतावनी देते हैं। लेकिन चलो चेतावनी को अनदेखा करते हैं।

$ gcc -std=c99 -pedantic -W -Wall func.c main.c -o test 
func.c:1: warning: unused parameter 'a' 
main.c: In function 'main': 
main.c:4: warning: implicit declaration of function 'f' 
$ ./test 
0.000000 

यह 1 प्रिंट नहीं था, लेकिन मुद्रित 0. इसका कारण यह है संकलक मान लिया है कि f() एक int लौट आए, और काम d = f(); कि "int" एक double में बदला। कंपाइलर ने अभी भी कोड संकलित किया क्योंकि यह नहीं बता सका कि f() को परिभाषित नहीं किया गया था (स्पष्ट रूप से) घोषित किया गया था। लेकिन उपर्युक्त प्रोग्राम को संकलित करना मानक द्वारा आवश्यक नहीं है, इसलिए संकलक इसे अस्वीकार कर सकता था (उदाहरण के लिए gcc -Werror के साथ प्रयास करें!)

अगर हम एक फ़ाइल में सब कुछ है:

$ cat func.c >>main.c 
$ gcc -std=c99 -pedantic -W -Wall func.c main.c -o test 
main.c:4: warning: implicit declaration of function 'f' 
main.c: At top level: 
main.c:9: error: conflicting types for 'f' 
main.c:4: error: previous implicit declaration of 'f' was here 
main.c:9: warning: unused parameter 'a' 

अब संकलक संघर्ष देखता है, और आपको एक त्रुटि संदेश देता है। लेकिन, उपरोक्त कार्यक्रम को अस्वीकार करने के लिए एक कंपाइलर की आवश्यकता नहीं है, यह हो सकता है या नहीं।

सबसे compilers पहला कार्यक्रम को अस्वीकार नहीं करता है, तो आप एक और अनुवाद इकाई या नहीं में समारोह f() की सही परिभाषा है, क्योंकि वे नहीं जानते है। उन्होंने दूसरे कार्यक्रम को अस्वीकार कर दिया क्योंकि वे जानते हैं जो आप नहीं करते हैं।

6

सी मान लेगा कि एक समारोह में प्रोटोटाइप int func() है; जब तक आप इसे अन्यथा बताया है। (ध्यान दें कि सी में पूर्णांक समारोह(); और पूर्णांक समारोह (शून्य), अलग अलग बातें कर रहे हैं)

अपने दूसरे मामले में, आप f() के लिए एक कॉल करना है जिसके लिए संकलक नहीं है किसी भी प्रोटोटाइप को देखा, तो यह मानता है कि यह int f(); है। बाद में यह f() के लिए आपकी परिभाषा को देखता है जिसमें एक अलग प्रोटोटाइप होता है - और एक त्रुटि जारी करता है।

यह 1 मामले में नहीं होता है, क्योंकि वे विभिन्न संकलन इकाइयों में हैं।

0

आपका पहला उदाहरण कभी भी func.c का उपयोग नहीं करता है, इसलिए मुझे यकीन नहीं है कि संकलक f() के बारे में क्या कर रहा है क्योंकि इसकी कोई परिभाषा नहीं है।

दूसरे उदाहरण में, मुझे नहीं पता कि आपके पास अलग-अलग हस्ताक्षरों के साथ दो फ़ंक्शन क्यों नहीं हो सकते हैं, लेकिन आप जिस फ़ंक्शन को परिभाषित करते हैं उसे कॉल नहीं कर रहे हैं। आप f() पर कोई तर्क नहीं देते हैं, लेकिन f आप परिभाषित करते हैं कि एक int लेता है जो इसे एक अलग फ़ंक्शन बनाता है।

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