2012-06-18 16 views
7

मैं कुछ कोड देख रहा था जिसे एक दोस्त ने मुझे भेजा था, और उसने कहा: "यह संकलित करता है, लेकिन काम नहीं करता"। मैंने देखा कि वह कोष्ठकों कार्यों के लिए इस्तेमाल किया, कुछ इस तरह:जब मैं ब्रांड्स के बिना फ़ंक्शंस का उपयोग करता हूं तो C++ संकलक शिकायत क्यों नहीं करता है?

void foo(){ 
    cout<< "Hello world\n"; 
} 

int main(){ 
    foo; //function without parentheses 
    return 0; 
} 

पहले मैं था "उपयोग कोष्ठक, आप के लिए है" कहा। और फिर मैंने उस कोड का परीक्षण किया - यह संकलित करता है, लेकिन जब निष्पादित किया जाता है तो काम नहीं करता है (नहीं "हैलो वर्ल्ड" दिखाया गया है)।

तो, यह संकलन क्यों करता है (कंपाइलर जीसीसी 4.7 से बिल्कुल कोई चेतावनी नहीं), लेकिन काम नहीं करता है?

+0

यह वास्तव में काम करता है। 'foo' को एक फ़ंक्शन पॉइंटर के रूप में माना जाता है। रेखा 'foo;' प्रभाव के बिना सिर्फ एक रेखा है। यदि आप अपनी चेतावनियों को अधिकतम में बदल देते हैं तो आपको बिना किसी बयान के बारे में चेतावनी मिलनी चाहिए। – RedX

+0

मैं देखता हूं * "चेतावनी: कथन एक संदर्भ है, कॉल नहीं, 'foo'" * और * "चेतावनी: कथन का कोई प्रभाव नहीं है" *। आप शायद -Wall -Wextra – Flexo

+3

के साथ संकलित करना चाहते हैं (भविष्य के प्रश्नों के लिए अपने नमूने को पूरा करने के लिए '# शामिल ' और किसी भी नेमस्पेस सामान को डालने के लायक है) – Flexo

उत्तर

12

यह निश्चित रूप से चेतावनी देता है कि क्या आप चेतावनी स्तर को काफी अधिक सेट करते हैं।

फ़ंक्शन का नाम फ़ंक्शन के पते पर मूल्यांकन करता है, और यह एक कानूनी अभिव्यक्ति है। आमतौर पर यह एक फ़ंक्शन पॉइंटर में सहेजा जाता है,

void (*fptr)() = foo; 

लेकिन इसकी आवश्यकता नहीं है।

11

आपको उपयोग किए जाने वाले चेतावनी स्तर को बढ़ाने की आवश्यकता है। foo; एक वैध अभिव्यक्ति कथन है (फ़ंक्शन का नाम नामित फ़ंक्शन पर पॉइंटर में परिवर्तित होता है) लेकिन इसका कोई प्रभाव नहीं पड़ता है।

मैं आमतौर पर -std=c++98 -Wall -Wextra -pedantic का उपयोग देता है:

<stdin>: In function 'void foo()': 
<stdin>:2: error: 'cout' was not declared in this scope 
<stdin>: In function 'int main()': 
<stdin>:6: warning: statement is a reference, not call, to function 'foo' 
<stdin>:6: warning: statement has no effect 
3
foo; 

आप वास्तव में यहाँ समारोह 'का उपयोग कर' नहीं कर रहे हैं। आप बस इसके पते का उपयोग कर रहे हैं। इस मामले में, आप इसे ले रहे हैं लेकिन वास्तव में इसका उपयोग नहीं कर रहे हैं।

फ़ंक्शंस के पते (यानी उनके नाम, बिना किसी कंस्ट्रैसिस के) उपयोगी होते हैं जब आप उस फ़ंक्शन को किसी अन्य फ़ंक्शन पर कॉलबैक के रूप में पास करना चाहते हैं।