क्या कार्य करने के लिए एक पॉइंटर को नए-आवंटित करना कानूनी है?


33

फ़ंक्शन के पॉइंटर्स सादे डेटा पॉइंटर्स नहीं हैं क्योंकि वे एक शून्य * पॉइंटर में संग्रहीत नहीं किए जा सकते हैं। बहरहाल, ऐसा लगता है कि मैं नीचे दिए गए कोड की तरह फ़ंक्शन मेमोरी-पॉइंटर की कॉपी को डायनामिक मेमोरी (gcc और clang में) की तरह स्टोर कर सकता हूं। क्या ऐसा कोड C ++ मानक के अनुसार कानूनी है, या शायद यह किसी प्रकार का संकलक विस्तार है?

इसके अलावा, फ़ंक्शन-पॉइंटर में परिणामी सूचक एक सादे डेटा पॉइंटर के रूप में व्यवहार करता है: मैं इसे void * में संग्रहीत कर सकता हूं और इसे static_cast द्वारा void * से पुनर्प्राप्त कर सकता हूं। क्या यह व्यवहार मानक के अनुसार है?

int main()
{
  extern void fcn();
  void (*fcnPtr)() = &fcn;
  void (**ptrToFcnPtr)() = nullptr;

  //Make the copy of fcnPtr on the heap:
  ptrToFcnPtr = new decltype(fcnPtr)(fcnPtr);
  //Call the pointed-to function : 
  (**ptrToFcnPtr)();

  //Save the pointer in void* :
  void *ptr = ptrToFcnPtr;
  //retrieve the original ptr: 
  auto myPtr = static_cast< void(**)() > (ptr) ; 
  //free memory:
  delete ptrToFcnPtr ;

}

2
कृपया कच्चे फ़िसटोन पॉइंटर्स का उपयोग न करें। std::functionइसके बजाय उपयोग करें ।
कुछ प्रोग्रामर दोस्त

आपको newकास्ट करने की आवश्यकता नहीं है void*void* ptr = &fcnPtr;सिर्फ एक काम करता है, क्योंकि fcnPtrएक वस्तु है, एक फ़ंक्शन नहीं है।
अखरोट

5
@Someprogrammerdude std::functionएक प्रकार का मिटाया हुआ कंटेनर है जो मनमाने ढंग से कॉल करने योग्य है, वास्तव में फ़ंक्शन पॉइंटर्स के लिए प्रतिस्थापन नहीं ...
माइकल केन्ज़ेल

7
(@Someprogrammerdude) कृपया आँख बंद करके उपयोग / सिफारिश न करें std::function । यह "पॉलीमॉर्फिक" फ़ंक्शंस को स्टोर करने की अपनी क्षमता के लिए बहुत अच्छा है (यानी सही हस्ताक्षर के साथ कुछ भी, भले ही इसमें कुछ लैंबडास के मामले में राज्य हो), लेकिन यह भी उपरि जोड़ता है जिसकी आवश्यकता नहीं हो सकती है। किसी फ़ंक्शन का पॉइंटर POD है। ए std::functionनहीं है।
मैथ्यू

2
@ मैथ्यू निष्पक्ष होने के लिए, एड्रियन गतिशील रूप से कार्य करने के लिए सूचक को आवंटित करने और इसे टाइप-मिटाने के साथ इंगित करने के बारे में पूछ रहा है void*, इसलिए इस प्रश्न के संदर्भ में std::functionठीक वही लगता है जो वे खोज रहे थे। मैं इस बात से सहमत हूं कि फ़ंक्शन पॉइंटर्स की एसपीडी सामान्य बर्खास्तगी असत्य है।
एरोरिका

जवाबों:


27

जबकि फंक्शन पॉइंट्स ऑब्जेक्ट पॉइंटर्स नहीं होते हैं, "पॉइंटर टू फंक्शन ऑफ टाइप" अभी भी ऑब्जेक्ट टाइप है [basic.types] / 8 । इस प्रकार, फंक्शन पॉइंटर्स स्वयं ऑब्जेक्ट हैं, बस जिस चीज को वे इंगित करते हैं वह नहीं है।

इस प्रकार, आप एक नई अभिव्यक्ति के माध्यम से फ़ंक्शन पॉइंटर प्रकार की एक वस्तु बना सकते हैं ...


9

जैसा कि वे (फ़ंक्शन पॉइंटर्स) एक शून्य * पॉइंटर में संग्रहीत नहीं किया जा सकता है।

वास्तव में, एक फ़ंक्शन पॉइंटर को एक void*सशर्त रूप से समर्थित के रूप में संग्रहीत करना । इसका मतलब यह है कि या तो यह भाषा के कार्यान्वयन के आधार पर संग्रहीत किया जा सकता है या नहीं किया जा सकता है। यदि भाषा कार्यान्वयन गतिशील लोडिंग का समर्थन करता है, तो void*संभवतः फ़ंक्शन पॉइंटर को परिवर्तित करना समर्थित है। GCC, Clang और MSVC सभी इसका समर्थन करते हैं:

reinterpret_cast<void*>(&function);

क्या कार्य करने के लिए एक पॉइंटर को नए-आवंटित करना कानूनी है?

ज़रूर। फ़ंक्शन पॉइंटर्स सहित सभी पॉइंटर्स ऑब्जेक्ट हैं और सभी ऑब्जेक्ट्स को गतिशील रूप से आवंटित किया जा सकता है।

इसके अलावा, फ़ंक्शन-पॉइंटर में परिणामी पॉइंटर एक सादे डेटा पॉइंटर के रूप में व्यवहार करता है

फ़ंक्शन पॉइंटर एक ऑब्जेक्ट है। एक फ़ंक्शन पॉइंटर को इंगित करता है कि न केवल "जैसा व्यवहार करता है", बल्कि है एक वस्तु के लिए सूचक।

मैं इसे void * में स्टोर कर सकता हूं और इसे static_cast द्वारा शून्य * से पुनर्प्राप्त कर सकता हूं। क्या यह व्यवहार मानक के अनुसार है?

शून्य और सूचक को ऑब्जेक्ट के लिए पॉइंटर के बीच रूपांतरण की अनुमति है, हाँ। और मूल पॉइंटर उपज के लिए गोल-यात्रा रूपांतरण की गारंटी है।


धन्यवाद। लेकिन फिर फ़ंक्शन-पॉइंटर को शून्य में बदलने के लिए * (या आसपास का अन्य तरीका) मुझे रीइंटरप्रिट_का उपयोग करने की आवश्यकता है, है ना?
एड्रियन

1
@ एड्रियन हाँ। मैंने एक उदाहरण जोड़ा।
एरोरिका

अगर किसी को शायद एक अपवाद चाहिए: डॉस मध्यम मेमोरी मॉडल + ओवरले। मध्यम मॉडल में डेटा पॉइंटर्स की तुलना में फंक्शन पॉइंटर्स बड़े होते हैं, और यदि आप पर्याप्त प्रयास करते हैं तो प्लगइन्स प्राप्त करने के लिए ओवरले का उपयोग किया जा सकता है।
जोशुआ
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.