C में फ़ंक्शन का आकार हमेशा 1 बाइट क्यों होता है?


87

जब हम किसी फ़ंक्शन का उपयोग करके जांच करते हैं sizeof(), तो हमें हमेशा 1 बाइट मिलता है । यह 1 बाइट क्या दर्शाता है?

जवाबों:


80

यह एक बाधा का उल्लंघन है, और आपके संकलक को इसका निदान करना चाहिए । यदि यह इसके बावजूद इसे संकलित करता है, तो आपके कार्यक्रम में अपरिभाषित व्यवहार है [विफलता मोड के स्पष्टीकरण के लिए @Steve Jessop का धन्यवाद, और कुछ कंपाइलर इसकी अनुमति क्यों देते हैं, इसके लिए @Michael Burr का उत्तर देखें : C11, 6.5.3.4./ 1:

sizeofऑपरेटर एक अभिव्यक्ति समारोह प्रकार है कि करने के लिए लागू नहीं किया जाएगा


11
यह एक बाधा है, जिसका अर्थ है एक अनुरूप संकलक में इसका निदान किया जाता है। यदि कंपाइलर इसे वैसे भी संकलित करता है (इसका निदान किया गया है), तो व्यवहार अपरिभाषित है। यदि कंपाइलर इसका निदान नहीं करता है (जो उदाहरण के लिए gcc के बिना नहीं है -pedantic), तो आपके पास एक गैर-संकलित कंपाइलर है और हर प्रोग्राम में अपरिभाषित व्यवहार होता है।
स्टीव जेसोप

1
व्यवहार इसे GNU C एक्सटेंशन के समान श्रेणी में रखता है, लेकिन मुझे नहीं पता कि कोई भी उस व्यवहार को क्यों चाहता है, इसलिए मुझे नहीं पता कि GNU लेखक इसे जोड़ने के लिए अपने रास्ते से बाहर क्यों चले गए।
स्टीव जेसप

1
@SteveJessop: ध्यान दें कि यह साथ भी है -std=c11, नहीं gnu11 । यह वास्तव में अजीब संकलक विस्तार है।
केरेक एसबी

6
ऊह! मुझे लगता है कि यह फ़ंक्शन पॉइंटर्स पर अंकगणित को सक्षम करने के लिए है, उसी तरह जो sizeof(void)जीएनयू सी में 1 है
स्टीव जेसप

3
के बारे में -std=c11: किसी -std=c*को विज्ञापन मानकों के विकल्पों का उल्लेख करना चाहिए । वे अनुरूपता मोड को सक्षम नहीं करते हैं, वे केवल एक्सटेंशन को अक्षम करते हैं जो एक अच्छी तरह से गठित प्रोग्राम को संकलित करने से रोकते हैं (जैसे कि typeofएक कीवर्ड के रूप में, चूंकि एक अच्छी तरह से गठित सी प्रोग्राम इसे एक चर नाम के रूप में उपयोग कर सकता है, लेकिन gccडिफ़ॉल्ट रूप से इसे अस्वीकार कर देगा )। अतिरिक्त रूप से अक्षम किए गए एक्सटेंशनों को अक्षम करने के लिए जो अन-बन चुके प्रोग्रामों को अपरिवर्तित पास करने की अनुमति देते हैं, आपको आवश्यकता है -pedanticया -pedantic-errors
स्टीव जेसप

56

यह अपरिभाषित व्यवहार नहीं है - sizeofऑपरेटर के लिए एक बाधा उल्लंघन के बाद से सी भाषा मानक को एक फ़ंक्शन डिज़ाइनर (एक फ़ंक्शन नाम) के साथ ऑपरेटर का उपयोग करते समय एक निदान की आवश्यकता होती है sizeof

हालांकि, सी भाषा के विस्तार के रूप में, जीसीसी voidपॉइंटर्स और फ़ंक्शन पॉइंटर्स पर अंकगणित की अनुमति देता है , जो कि voidया किसी फ़ंक्शन के आकार का इलाज करके किया जाता है 1। परिणामस्वरूप, sizeofऑपरेटर के लिए मूल्यांकन करेंगे 1के लिए voidजीसीसी के साथ एक समारोह या। Http://gcc.gnu.org/onbuildocs/gcc/Pointer-Arith.html#Pointer-Arith देखें

आप sizeofइन परिचालकों के साथ -pedanticया का उपयोग करते समय चेतावनी जारी करने के लिए GCC प्राप्त कर सकते हैं-Wpointer-arith जीसीसी के विकल्पों विकल्पों । या इसके साथ त्रुटि करें -Werror=pointer-arith


आपका तर्क त्रुटिपूर्ण है। C को कुछ के लिए नैदानिक ​​संदेशों की आवश्यकता होती है, लेकिन सभी UB की नहीं। आप यह नहीं बता सकते कि किसी चीज़ ने व्यवहार को परिभाषित किया है क्योंकि वहाँ एक निदान है।
एमएसलटर्स

4
सी को सभी बाधा उल्लंघन (5.1.1.3 निदान C99 या C11 में) के लिए एक नैदानिक ​​की आवश्यकता होती है। एक बाधा (C99 / C11 में 3.8) एक "प्रतिबंध, या तो वाक्यविन्यास या शब्दार्थ है, जिसके द्वारा भाषा के तत्वों की व्याख्या की जानी है", जो यह कहता है कि बाधाओं का पालन नहीं करने वाली चीज़ की व्याख्या नहीं की जा सकती है ।
माइकल बूर

3
और स्पष्ट होना - एक बाधा का उल्लंघन अपरिभाषित व्यवहार के परिणामस्वरूप नहीं होता है। यह एक वाक्यविन्यास त्रुटि की तरह एक त्रुटि है। उदाहरण के लिए, मानक कहता है, "अगर एक" होगा "या" नहीं होगा "की आवश्यकता है जो एक बाधा के बाहर प्रकट होती है, उल्लंघन किया जाता है, तो व्यवहार अपरिभाषित है"। यदि एक बाधा उल्लंघन का परिणाम यूबी में होगा, तो मानक केवल "उथले" और "नहरों" के बारे में बात क्यों करेगा जो यहां बाधाओं में नहीं हैं?
माइकल ब्यूर

3
मैं वास्तव में यूबी के बारे में बहुत कुछ नहीं बताता था, सिवाय इसके कि sizeofएक फ़ंक्शन यूबी नहीं है (जिसका मैंने केवल बहुत अधिक उल्लेख किया क्योंकि अन्य उत्तर में कहा गया था कि यह यूबी है)। लेकिन शायद मैंने इस बात को गलत समझा कि जिस तरह से मैंने वाक्य को संरचित किया था। अधिक स्पष्ट होना। sizeofएक फ़ंक्शन यूबी नहीं है (जैसा कि कई उत्तरों ने दावा किया है)। यह एक बाधा का उल्लंघन है। जैसे, यह एक निदान की आवश्यकता है। जीसीसी इसे एक विस्तार के रूप में अनुमति देता है।
माइकल ब्यूर

2
@KerrekSB: ओपी को डायग्नोस्टिक नहीं मिलता है क्योंकि संभवतः वे जीसीसी का उपयोग कर रहे हैं, जो सी भाषा एक्सटेंशन के रूप में इस उपयोग की अनुमति देता है।
माइकल बूर

13

यह दर्शाता है कि संकलक लेखक ने आपकी नाक से राक्षसों को उड़ने के बजाय 1 के मूल्य पर फैसला किया (वास्तव में, यह इसका एक और अपरिभाषित उपयोग था sizeofजिसने हमें यह अभिव्यक्ति दी: "सी संकलक खुद एक निदान जारी करना आवश्यक है, अगर यह पहली आवश्यकता है) डायग्नोस्टिक आपके प्रोग्राम के परिणामस्वरूप, और फिर MAY खुद राक्षसों को आपकी नाक से उड़ान भरने का कारण बनता है (जो, वैसे, प्रलेखित डायग्नोस्टिक संदेश को अच्छी तरह से बीई कर सकता है) क्योंकि यह सिंटैक्स नियमों या बाधाओं के आगे के उल्लंघन के लिए डायग्नोस्टिक जारी करता है (या,) उस मामले के लिए, किसी भी कारण से यह चुनता है)। " https://groups.google.com/forum/?fromgroups=#=msg/comp.std.c/ycpVKxTZkgw/S2hHdTbvd8d8J

इससे एक अनिर्णीत निर्माण के जवाब में संकलक जो भी करने का फैसला करता है, उसके लिए "नक्सल दानव" है। 1इस मामले के लिए इस संकलक का नाक दानव है।


@ इल्मारियारोनें मुझे स्वीकार करना होगा, हालांकि, सी (और सी ++) पर मेरे अधिकांश जवाब या तो सामान्य भाषा-अज्ञेय सिद्धांतों या उस तरह के ऐतिहासिक सोने की डली पर हैं। मेरा सी अनुभव अपने आप में ऐतिहासिक है :)
जॉन हैना

7

जैसा कि अन्य ने बताया है, sizeof () कोई भी वैध पहचानकर्ता ले सकता है, लेकिन यह फ़ंक्शन नामों के लिए एक वैध (एक ईमानदारी से सच और वैध) परिणाम नहीं लौटाएगा। इसके अलावा, यह निश्चित रूप से हो सकता है, या "राक्षसों के नाक से बाहर" सिंड्रोम के परिणामस्वरूप हो सकता है।

यदि आप अपने प्रोग्राम फंक्शन साइज़ को प्रोफाइल करना चाहते हैं, तो लिंकर मैप को देखें, जो कि इंटरमीडिएट रिजल्ट डायरेक्टरी पर पाया जा सकता है। कभी-कभी इस मैप फ़ाइल को जेनरेट करने या न करने का विकल्प होता है ... यह कंपाइलर / लिंकर पर निर्भर है।

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


1
किस प्रकार का कथन है "यह निश्चित रूप से हो सकता है या नहीं" ??? यह सब कुछ सचमुच नहीं है?
केरेक एसबी

@KerrekSB हां, लेकिन यहां यह कुछ भी कर सकता है या नहीं कर सकता है, और अभी भी नियमों के भीतर है। यह सच है कि एक संकलक संकलन करने से इनकार कर सकता है या नहीं कर सकता है, int x = 1;लेकिन उनमें से केवल एक मानकों के अनुरूप संकलक के लिए अनुमति है। sizeof()किसी फ़ंक्शन पर लागू होने के साथ , यह एक निर्धारित मान वापस नहीं कर सकता है, या उस समय एक विशेष रजिस्टर में जो कुछ भी है, उसके आधार पर एक यादृच्छिक मूल्य को संकलित करने या वापस करने से इनकार कर सकता है। शाब्दिक नाक राक्षसों की संभावना नहीं है, लेकिन मानक के पत्र के भीतर।
जॉन हन्ना

@ स्ट्रेक यह किसी भी चीज के लिए सच हो सकता है या किसी भी चीज के लिए गलत नहीं हो सकता है ... इसे फजी इल्लीगल होने के रूप में देखें।
jpinto3912

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