फ़ंक्शन घोषणा एक प्रोटोटाइप नहीं है


158

मेरे पास एक पुस्तकालय है, जिसे मैंने बनाया है,

mylib.c:

#include <mylib.h>
int
testlib() {
    printf("Hello world\n");
    return (0);
}

mylib.h:

#include <stdio.h>
extern int testlib();

मेरे कार्यक्रम में, मैंने इस लाइब्रेरी फ़ंक्शन को कॉल करने का प्रयास किया है:

myprogram.c:

#include <mylib.h>

int
main (int argc, char *argv[]) {
    testlib();
    return (0);
}

जब मैं इस कार्यक्रम को संकलित करने का प्रयास करता हूं तो मुझे निम्नलिखित त्रुटि मिलती है:

Myprogram.c: 1 से शामिल फ़ाइल में
mylib.h: 2 चेतावनी: फ़ंक्शन घोषणा एक प्रोटोटाइप नहीं है

मैं उपयोग कर रहा हूँ: gcc (GCC) 3.4.5 20051201 (Red Hat 3.4.5-2)

मेरा प्रश्न यह है कि फंक्शन प्रोटोटाइप घोषित करने का उचित तरीका क्या है?


1
Mylib.h में घोषणा से बाहरी को हटा दें। खासकर यदि आप शुद्ध सी प्रोग्राम लिख रहे हैं, तो बाहरी घोषणा अनावश्यक है।
रयान आहर्न

जवाबों:


333

C में int foo()और int foo(void)विभिन्न कार्य हैं। 0 तर्कों int foo()को int foo(void)स्वीकार करते हुए, मनमानी संख्या को स्वीकार करता है। C ++ में उनका मतलब वही होता है। मेरा सुझाव है कि voidजब आप कोई तर्क नहीं देते हैं तो आप लगातार उपयोग करते हैं।

यदि आपके पास एक चर है a, extern int a;तो संकलक को बताने का एक तरीका है जो aएक प्रतीक है जो एक अलग अनुवाद इकाई में मौजूद हो सकता है (सी संकलक स्रोत फ़ाइल के लिए बोलता है), लिंक समय तक इसे हल न करें। दूसरी ओर, प्रतीक जो फ़ंक्शन नाम हैं, वैसे भी लिंक समय पर हल किए जाते हैं। एक समारोह पर एक भंडारण वर्ग विनिर्देशन का अर्थ ( extern, static) केवल उसकी दृश्यता को प्रभावित करता है और externडिफ़ॉल्ट है, इसलिए externवास्तव में अनावश्यक है।

मैं externइसे हटाने का सुझाव देता हूं , यह बाहरी है और आमतौर पर छोड़ा जाता है।


9
(void) C का उपयोग यह इंगित करने के लिए करता है कि कोई फ़ंक्शन कोई तर्क नहीं लेता है। C ++ में, जब तक कि आपको विशेष रूप से C और C ++ दोनों को संकलित करने के लिए अपने कोड की आवश्यकता नहीं है, तब तक उपयोग करें ()
कीथ थॉम्पसन

49

त्वरित उत्तर: यह निर्दिष्ट int testlib()करने के int testlib(void)लिए परिवर्तन कि फ़ंक्शन कोई तर्क नहीं लेता है।

एक प्रोटोटाइप एक फ़ंक्शन घोषणा है जो फ़ंक्शन के तर्क (प्रकार) को निर्दिष्ट करता है।

एक गैर-प्रोटोटाइप फ़ंक्शन घोषणा की तरह

int foo();

एक पुरानी शैली की घोषणा है जो संख्या या प्रकार के तर्कों को निर्दिष्ट नहीं करती है। (1989 एएनएसआई सी मानक से पहले, यह भाषा में उपलब्ध एकमात्र प्रकार की फ़ंक्शन घोषणा है।) आप इस तरह के फ़ंक्शन को किसी भी मनमानी संख्या के साथ कॉल कर सकते हैं, और कंपाइलर को शिकायत करने की आवश्यकता नहीं है - लेकिन अगर कॉल परिभाषा के साथ असंगत है , आपके कार्यक्रम में अपरिभाषित व्यवहार है।

एक फ़ंक्शन के लिए जो एक या अधिक तर्क लेता है, आप घोषणा में प्रत्येक तर्क के प्रकार को निर्दिष्ट कर सकते हैं:

int bar(int x, double y);

बिना किसी तर्क के कार्य एक विशेष मामला है। तार्किक रूप से, खाली कोष्ठक एक तर्क को निर्दिष्ट करने का एक अच्छा तरीका होता, लेकिन वह वाक्य-विन्यास पहले से ही पुरानी शैली के फ़ंक्शन घोषणाओं के लिए उपयोग में था, इसलिए ANSI C समिति ने voidकीवर्ड का उपयोग करके एक नया सिंटैक्स का आविष्कार किया :

int foo(void); /* foo takes no arguments */

एक समारोह परिभाषा (जिसमें फ़ंक्शन वास्तव में क्या करता है के लिए कोड शामिल है) एक घोषणा भी प्रदान करता है । आपके मामले में, आपके पास कुछ समान है:

int testlib()
{
    /* code that implements testlib */
}

यह एक गैर-प्रोटोटाइप घोषणा प्रदान करता है testlib। एक परिभाषा के रूप में, यह संकलक को बताता है testlibजिसका कोई पैरामीटर नहीं है, लेकिन एक घोषणा के रूप में, यह केवल संकलक को बताता है जो testlibकुछ अनिर्दिष्ट लेकिन निश्चित संख्या और तर्कों के प्रकार लेता है।

आप को बदलते हैं ()करने के लिए (void)घोषणा एक प्रोटोटाइप बन जाता है।

एक प्रोटोटाइप का लाभ यह है कि यदि आप गलती testlibसे एक या अधिक तर्कों के साथ कॉल करते हैं, तो संकलक त्रुटि का निदान करेगा।

(C ++ में थोड़े अलग नियम हैं। C ++ में पुरानी शैली की फ़ंक्शन घोषणाएं नहीं हैं, और खाली कोष्ठक का विशेष रूप से मतलब है कि एक फ़ंक्शन कोई तर्क नहीं लेता है। C ++ (void)सी के साथ संगतता के लिए सिंटैक्स का समर्थन करता है, लेकिन जब तक आपको विशेष रूप से दोनों को संकलित करने के लिए आपके कोड की आवश्यकता नहीं होती है। C और C ++ के रूप में, आपको संभवतः ()C ++ और C में (void)सिंटैक्स का उपयोग करना चाहिए )


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.