टाइपपीफ-एड फ़ंक्शन पॉइंटर्स को कार्यों के पैरामीटर में योग्यता प्राप्त करने के संबंध में सी मानक का क्या कहना है? उदाहरण के लिए, मान लें कि मेरे पास निम्न प्रकार है

typedef int (*Operation)(int a, int b);

मेरे पास संचालन का एक गुच्छा है जो दो इंच लेता है, ऑपरेशन करता है, और फिर एक int देता है। तब मेरे पास एक ऐसा फ़ंक्शन होता है जो वास्तविक फ़ंक्शन पॉइंटर कॉल करता है।

int doOpOnce(const Operation op, int a, int b)
{
    return op(a, b);
}

मैं गारंटी देना चाहता हूं कि doOpOnce कॉल के दौरान फ़ंक्शन पॉइंटर नहीं बदलता है और मैं doOpOnce के उपयोगकर्ताओं को भी दस्तावेज़ देना चाहता हूं कि यह वास्तव में दिए गए फ़ंक्शन को कॉल करेगा। क्या यह मान्य है? क्या इसमें कोई अंतर है:

int doOpOnce(const Operation op, int a, int b)
int doOpOnce(Operation const op, int a, int b)

अंत में, यहाँ एक उदाहरण है। यह जीसीसी 4.9.2 के साथ झंडे -std=c99 -Wall -Wextra -pedantic के साथ संकलित है और जब मैं अपने कॉन्स्ट फ़ंक्शन पॉइंटर को बदलने का प्रयास करता हूं तो यह सही ढंग से त्रुटियां होती है।

#include <stdio.h>

typedef int (*Operation)(int a, int b);

int opAdd(int a, int b)
{
    return a + b;
}

int opSub(int a, int b)
{
    return a - b;
}

int doOpOnce(const Operation op, int a, int b)
{
    op = opSub; // error: assignment of read-only parameter 'op'

    return op(a, b);
}

int main()
{
    printf("%d\n", doOpOnce(opAdd, 10, 20));

    return 0;
}

मैं कॉन्स्टेबल क्वालीफायर को Operation टाइपपीफ में नहीं जोड़ना चाहता क्योंकि मेरे पास अन्य फ़ंक्शन हैं जो Operation पॉइंटर्स को संशोधित कर सकते हैं। मैं बस कुछ परिस्थितियों में मजबूत टाइपिंग चाहता हूं।

1
thndrwrks 18 सितंबर 2017, 20:13

3 जवाब

सबसे बढ़िया उत्तर

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

आपके अन्य प्रश्न को हल करने के लिए, const के दो प्लेसमेंट का एक ही अर्थ है, इसलिए आप जो चाहें चुन सकते हैं।

1
templatetypedef 18 सितंबर 2017, 20:25

बाहरी दुनिया (.h) को int doOpOnce(Operation op, int a, int b); देखें और आपकी .c फ़ाइल int doOpOnce(Operation const op, int a, int b) { को लागू करें ताकि "यह सुनिश्चित करने के लिए कि doOpOnce के दौरान फ़ंक्शन पॉइंटर नहीं बदलता है"


"मैं doOpOnce के उपयोगकर्ताओं को यह भी दस्तावेज़ करना चाहता हूं कि यह वास्तव में इसे दिए गए फ़ंक्शन को कॉल करेगा।" कोड दस्तावेज़ीकरण में है।

int doOpOnce(Operation const op, int a, int b); का एक फ़ंक्शन घोषणा हस्ताक्षर "यह वास्तव में इसे दिए गए फ़ंक्शन को कॉल करेगा" की गारंटी के लिए पर्याप्त नहीं है।

1
chux - Reinstate Monica 18 सितंबर 2017, 20:24

फ़ंक्शन के उपयोगकर्ता के लिए doOpOnce यह महत्वहीन है कि पॉइंटर को const क्वालिफायर के साथ घोषित किया गया है या नहीं, क्योंकि फ़ंक्शन उपयोगकर्ता द्वारा दिए गए मूल पॉइंटर की एक प्रति के रूप में एक तर्क के रूप में काम करता है।

फ़ंक्शन के उपयोगकर्ता के लिए ये दो फ़ंक्शन घोषणाएं

int doOpOnce(const Operation op, int a, int b);

तथा

int doOpOnce( Operation op, int a, int b);

एक ही समारोह घोषित करें। आप कार्यक्रम में दोनों घोषणाओं को शामिल कर सकते हैं।

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

0
Vlad from Moscow 18 सितंबर 2017, 20:39