साइज़ोफ़ इंट क्यों गलत है, जबकि साइज़ोफ़ (इंट) सही है?


96

हम जानते हैं कि sizeofकिसी भी डेटाटाइप और अभिव्यक्ति के आकार की गणना के लिए एक ऑपरेटर का उपयोग किया जाता है, और जब ऑपरेंड एक अभिव्यक्ति होता है, तो कोष्ठक को छोड़ा जा सकता है।

int main()
{
        int a;

        sizeof int;
        sizeof( int );
        sizeof a;
        sizeof( a );

        return 0;
}

पहला उपयोग sizeofगलत है, जबकि अन्य सही हैं।

जब इसे gcc का उपयोग करके संकलित किया जाता है, तो निम्न त्रुटि संदेश दिया जाएगा:

main.c:5:9: error: expected expression before int

मेरा सवाल है कि सी मानक इस तरह के संचालन की अनुमति क्यों नहीं देता है। sizeof intकिसी भी अस्पष्टता का कारण होगा ?


5
मजेदार बात यह है कि सभी अभिव्यक्तियाँ बिना कोष्ठक के स्वीकार नहीं की जाती हैं: कोशिश करें sizeof (int)a
फ्रेड फू

2
@MikkelK: ओपी मानक उद्धरणों के पीछे तर्क पूछ रहा है, जो पहले से ही चिह्नित उत्तर में उल्लिखित उद्धरणों को जानता है।
आलोक बचाओ

2
@ लुंडिन: वास्तव में संकलन का sizeof +(int)aलाभ है *&;-)
स्टीव जेसप

2
@SteveJessop आह ठीक है, यह एक अंतराल नहीं है। हालांकि यह Embarcadero C ++ में संकलित है, अजीब तरह से पर्याप्त है। वैसे भी, मेरा मानना ​​है कि हमें अभी unary + ऑपरेटर के लिए एक उपयोग मिला है! C प्रोग्रामिंग के इतिहास में ऐसा पहली बार होना चाहिए :)
लुंडिन

2
@ लुंडिन: आपको अभी भी एकता के साथ सावधान रहना होगा +। उदाहरण के लिए, sizeof +(char)a == sizeof(int)पूर्णांक पदोन्नति के कारण, यह शायद कम त्रुटि-प्रवण होता है, क्योंकि यदि आप जिस आकार का आकार लेने की कोशिश कर रहे हैं, उसके बारे में कोई चिंता नहीं है। इसलिए मुझे यकीन नहीं है कि मैं इसे "एक उपयोग" कहने के लिए बहुत दूर जाऊंगा, हालांकि मैं मानता हूं कि मैंने इसका इस्तेमाल किया है ...
स्टीव जेसप

जवाबों:


101

निम्नलिखित अस्पष्ट हो सकता है:

sizeof int * + 1

वह है (sizeof (int*)) + 1, या (sizeof(int)) * (+1)?

जाहिर है सी भाषा अस्पष्टता को हल करने के लिए एक नियम पेश कर सकती थी, लेकिन मैं सोच सकता हूं कि यह परेशान क्यों नहीं हुआ। भाषा के रूप में यह खड़ा है, एक प्रकार का विनिर्देशक अभिव्यक्ति में "नग्न" कभी नहीं दिखाई देता है, और इसलिए यह निर्धारित करने के लिए नियमों की कोई आवश्यकता नहीं है कि क्या दूसरा *प्रकार या अंकगणितीय ऑपरेटर का हिस्सा है।

मौजूदा व्याकरण पहले से ही संभावित अस्पष्टता को हल करता है sizeof (int *) + 1। यह है (sizeof(int*))+1, नहीं sizeof((int*)(+1))

C ++ में फ़ंक्शन-स्टाइल कास्ट सिंटैक्स के साथ हल करने के लिए कुछ समान मुद्दा है। आप लिख सकते हैं int(0)और आप लिख सकते हैं typedef int *intptr; intptr(0);, लेकिन आप लिख नहीं सकते int*(0)। उस स्थिति में, संकल्प यह है कि "नग्न" प्रकार एक साधारण प्रकार का नाम होना चाहिए, यह किसी भी पुराने प्रकार की आईडी नहीं हो सकती है जिसमें इसमें रिक्त स्थान हो, या विराम चिह्न अनुगामी हो। शायद sizeofउसी प्रतिबंध के साथ परिभाषित किया जा सकता था, मुझे यकीन नहीं है।


1
C ++ में new int*(X)अस्पष्टता होगी यदि C ++ ने यह निर्दिष्ट नहीं किया कि नया ऑपरेटर सबसे लंबा स्ट्रिंग लेता है जो संभवतः एक प्रकार हो सकता है। इसलिए सी ++ में वे साइजोफ के साथ समान बना सकते थे, मुझे लगता है। लेकिन सी ++ में आप कह सकते हैं sizeof int()कि तब अस्पष्ट (प्रकार या मूल्य इनिशियलाइज़ इंट?) होगा।
जोहान्स शाउब -

@ जोहान्सचैब-लिटब: मम्म, इसलिए शायद तब सी ++ यह कह सकता था कि यदि एक को पार्स करना संभव है, तो यह प्रकार पसंद किया जाता है, अन्यथा यह एक अभिव्यक्ति है। अस्पष्टता को हल किया जाएगा, लेकिन sizeof int()बीमार हो जाएगा ("नहीं के operator()लिए size_t"), जो मुझे उम्मीद है कि अवांछित होगा!
स्टीव जेसप

32

से C99 स्टैंडर्ड

6.5.3.4.2 ऑपरेटर अपनी संकार्य के आकार (बाइट्स में) है, जो एक अभिव्यक्ति या एक प्रकार की parenthesized नाम हो सकता है अर्जित करता है।
sizeof

आपके मामले intमें न तो अभिव्यक्ति है और न ही कोष्ठक नाम।


10
मुझे समझ में नहीं आता है कि यह 7 उत्थान क्यों हो जाता है। तीन हटाए गए उत्तरों की तरह, यह केवल यह समझाने की बजाय नियम को दोहराता है कि नियम क्यों मौजूद है।
फ्रेड फू

7
@ लार्समैन, हां, मैं आपसे सहमत हूं। हालाँकि यह नियम को दोहराना जारी रखता है, लेकिन कम से कम, यह पढ़ने को अधिकृत करने का एक टुकड़ा देता है।
यिशु फेंग

3
@ लार्समैन यदि हम C99 में किए गए हर निर्णय को सही ठहराने की कोशिश करने लगे तो हम यहाँ पूरे साल रहेंगे। मानक को उद्धृत करना इस चर्चा को लपेटने के लिए जितना अच्छा है उतना ही अच्छा तरीका है।
पेरी

1
@ चेरी: यदि आपको इस तरह का प्रश्न पसंद नहीं है, तो आप प्रश्न को तर्क के रूप में बंद करने के लिए मतदान कर सकते हैं।
फ्रेड फू

4
C ++ के एक गैर-प्रैक्टिशनर के रूप में, यहां तक ​​कि मैं इस उत्तर को समझता हूं, निश्चित नहीं कि समस्या क्या है यदि आप अंग्रेजी पढ़ और समझ सकते हैं।
केव

6

C. में sizeof ऑपरेटर का उपयोग करने के दो तरीके हैं। वाक्य रचना यह है:

C11 6.5.3 Unary operators
...
sizeof unary-expression
sizeof ( type-name )

जब भी आप ऑपरेंड के रूप में एक प्रकार का उपयोग करते हैं, तो आपके पास भाषा की वाक्य रचना परिभाषा द्वारा लघुकोष्ठक होना चाहिए। यदि आप एक अभिव्यक्ति पर आकार का उपयोग करते हैं, तो आपको कोष्ठक की आवश्यकता नहीं है।

सी मानक एक ऐसा उदाहरण देता है जहाँ आप इसे अभिव्यक्ति पर उपयोग करना चाहते हैं:

sizeof array / sizeof array[0]

हालांकि, स्थिरता के लिए, और ऑपरेटर पूर्वता से संबंधित बगों से बचने के लिए, मैं व्यक्तिगत रूप से हमेशा उपयोग करने की सलाह दूंगा (कोई भी स्थिति नहीं)।


@ जोहान्सचैब-लिटब मैं सहमत हूं कि यह कोई भी तर्क नहीं प्रदान करता है कि सी 90 मानक निर्दिष्ट करने पर सी मानक समिति कैसे तर्क देती है। आपको उनसे पूछना होगा ... यह बिना किसी औचित्य के जवाब देता है, हालांकि, सी इसे अनुमति नहीं देता है क्योंकि वाक्यविन्यास 6.5.3 में निर्दिष्ट है। ओपी भी के बीच अंतर के बारे में पता लग रहा था sizeof expressionऔर sizeof(type)है, जो इस जवाब से समझाया गया है।
लुंडिन

(रिकॉर्ड के लिए, मैंने C90 और C11 दोनों युक्तियों को पढ़ा है और न ही कोई स्पष्टीकरण दिया है।)
लुंडिन

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