2010-10-15 14 views
28

सी में, मुझे एक संरचना के आकार को जानने की आवश्यकता है, जिसमें फ़ंक्शन पॉइंटर्स हैं। क्या मुझे गारंटी दी जा सकती है कि सभी प्लेटफ़ॉर्म और आर्किटेक्चर पर:फ़ंक्शन पॉइंटर के आकार के बारे में क्या गारंटी है?

  • शून्य का आकार * फ़ंक्शन पॉइंटर के समान आकार है?
  • फ़ंक्शन पॉइंटर का आकार इसके रिटर्न प्रकार के कारण भिन्न नहीं है?
  • फ़ंक्शन पॉइंटर का आकार इसके पैरामीटर प्रकारों के कारण भिन्न नहीं है?

मुझे लगता है कि उत्तर इन सभी के लिए हाँ है, लेकिन मैं यह सुनिश्चित करना चाहता हूं। संदर्भ के लिए, मैं sizeof(struct mystruct) पर कॉल कर रहा हूं और कुछ भी नहीं।

उत्तर

29

C99 कल्पना, खंड 6.2.5, पैरा 27 से:

एक सूचक शून्य करने के लिए एक ही प्रतिनिधित्व और संरेखण एक चरित्र प्रकार के सूचक के रूप आवश्यकताओं होगा। इसी प्रकार, संगत प्रकारों के क्वालिफाइड या अनक्वाली संस्करणों के लिए संगत प्रकारों में प्रतिनिधित्व और संरेखण आवश्यकताएं होंगी। संरचना प्रकारों के सभी पॉइंटर्स एक ही प्रतिनिधित्व और संरेखण एक दूसरे के रूप में आवश्यकताओं के अनुरूप होंगे। सभी यूनियन प्रकारों के पॉइंटर्स के पास समान प्रतिनिधित्व और संरेखण एक दूसरे के रूप में आवश्यकताएं होनी चाहिए। प्वाइंटर्स अन्य प्रकारों के लिए समान प्रतिनिधित्व या संरेखण आवश्यकताएं नहीं होनी चाहिए।

तो नहीं; कोई गारंटी नहीं है कि void * फ़ंक्शन पॉइंटर रख सकता है।

और खंड 6.3.2.3, पैरा 8:

एक प्रकार के एक समारोह के लिए एक सूचक एक अन्य प्रकार की एक कार्य करने के लिए एक सूचक बदला जा सकता है और वापस फिर से; परिणाम मूल सूचक में बराबर की तुलना करेगा।

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

14

नहीं, नहीं, नहीं।

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

हालांकि, किसी भी समारोह सूचक एक और समारोह सूचक प्रकार [*] और वापस मूल्य trashing, उसी तरह है कि किसी भी वस्तु सूचक void* और वापस करने के लिए डाली जा सकती है, में बिना करने के लिए डाली जा सकती है। इसलिए फ़ंक्शन पॉइंटर्स के आकार के अनुसार उनके हस्ताक्षर के अनुसार यह आश्चर्यजनक होगा। अतिरिक्त स्थान के लिए कोई स्पष्ट "उपयोग" नहीं है, यदि आपको किसी भी तरह से कम स्थान पर समान मूल्य को स्टोर करने में सक्षम होना है और फिर वापस डालने पर इसे पुनर्प्राप्त करना है।

[*] धन्यवाद, स्कॉट।

+3

अधिक आम तौर पर: किसी भी फ़ंक्शन पॉइंटर को किसी अन्य फ़ंक्शन पॉइंटर प्रकार और पीछे में परिवर्तित किया जा सकता है। (सी 99 6.3.2.3/8) – schot

+0

@ स्कोट: ठीक है, उस स्थिति में यह वास्तव में उन्हें अलग-अलग आकार बनाने के लिए विपरीत होगा, क्योंकि आकार के बावजूद सभी फ़ंक्शन पॉइंटर प्रकारों को मानों के समान सेट का प्रतिनिधित्व करना होता है। अर्थात्, प्रत्येक समारोह का पता, साथ ही एक शून्य सूचक। –

+0

उत्कृष्ट जवाब। दूसरे दिन से मेरा प्रश्न संभावित नुकसान को यहां दिखाता है: http://stackoverflow.com/questions/3889541/issue-with-null-pointers-on-harvard-architecture-platform – Vicky

7

अन्य उत्तर के अलावा, विकिपीडिया इस कहते हैं:

http://en.wikipedia.org/wiki/Function_pointer

हालांकि सी और सी में समारोह संकेत ++ सरल पते के रूप में लागू किया जा सकता है, ताकि आम तौर पर sizeof(Fx)==sizeof(void *), सदस्य सी ++ में पॉइंटर्स को अक्सर "वसा पॉइंटर्स" के रूप में लागू किया जाता है, आमतौर पर दो या एक साधारण फ़ंक्शन पॉइंटर के आकार के तीन गुना आकार के लिए, वर्चुअल विरासत के साथ सौदा करें।

एक फ़ंक्शन पॉइंटर एक अमूर्त है। जब तक मानक की आवश्यकताओं को पूरा किया जाता है, तब तक कुछ भी संभव है। अर्थात। यदि आपके प्रोग्राम में 256 से कम फ़ंक्शंस हैं, तो फ़ंक्शन पॉइंटर्स को एक बाइट का उपयोग करके एनयूएल के मान 0 के साथ और भौतिक पते वाले तालिका में इंडेक्स के रूप में मान 1 से 255 के साथ लागू किया जा सकता है। यदि आप 255 फ़ंक्शंस से अधिक हैं, तो इसे 2 बाइट्स का उपयोग करने के लिए बढ़ाया जा सकता है।

+4

डाउनवॉटर: मैंने जो लिखा है वह गलत है, क्योंकि ...? – Secure

+0

मुझे नहीं लगता कि यह गलत कैसे है। यह वास्तव में एक कानूनी सी कार्यान्वयन की संभावना है, हालांकि अगर मैं ऐसा कर रहा था तो मुझे आश्चर्य होगा। – nategoose

+3

मेरा डाउनवोट नहीं था, लेकिन सी ++ सदस्य सूचक सामग्री अप्रासंगिक है क्योंकि प्रश्न सी के बारे में है। अंतिम पैराग्राफ एक बिल्कुल अच्छा बिंदु है, हालांकि, फंक्शन पॉइंटर्स निश्चित रूप से * कानूनी रूप से कुछ तालिका में एक सूचकांक हो सकता है, अतिरिक्त के साथ वास्तव में उन्हें कॉल करने के लिए संकेत का स्तर। –

1

अलग-अलग आकारों का एक व्यावहारिक उदाहरण है जो सामान्य होता था। एमएस-डॉस & प्रारंभिक विंडोज सी प्रोग्रामिंग में, "मध्यम" मेमोरी मॉडल में आपके पास 16-बिट डेटा पॉइंटर्स थे लेकिन 32-बिट फ़ंक्शन पॉइंटर्स थे, और "कॉम्पैक्ट" मेमोरी मॉडल एक और तरीका था।

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