कैसे "int * ptr = int ()" मूल्य आरंभीकरण अवैध नहीं है?


86

निम्न कोड (लिया यहां से गया ):

int* ptr = int();

Visual C ++ में संकलित करता है और पॉइंटर को मूल्य-आरंभ करता है।

वो कैसे संभव है? मेरा मतलबint() कि एक प्रकार की वस्तु मिलती है intऔर मैं intएक पॉइंटर को असाइन नहीं कर सकता ।

ऊपर का कोड अवैध कैसे नहीं है?


उत्तर नहीं, बल्कि महान प्रश्न! मैंने ऐसा कभी नहीं देखा।
जोश

6
चूंकि प्राइमिटिव्स के पास C ++ में एक 'कंस्ट्रक्टर' है, इसलिए (जो मुझे लगता है कि C ++ 03 निर्दिष्ट चीज़ है) का डिफ़ॉल्ट int()निर्माण मूल्य और पैदावार का मान प्राप्त करता है । यह intint0int *ptr = 0;
wkl

7
@EmanuelEy: नहीं, किसी शून्य-शून्य पूर्णांक स्थिरांक का उपयोग अशक्त सूचक स्थिरांक के रूप में किया जा सकता है, इस बात की परवाह किए बिना कि वास्तव में संकेत कैसे कार्यान्वित किए जाते हैं।
माइक सीमोर

1
@MooDDuck: मैंने नहीं कहा कि NULLयह एक गैर-शून्य मान हो सकता है। मैंने कहा कि यह किसी भी शून्य-मूल्यवान पूर्णांक स्थिरांक (जिसमें शामिल है int()) हो सकता है।
माइक सीमोर

5
@ डैनीलप्रिडेन "ऑब्जेक्ट" शब्द का एक उपयोग है, जिसके बारे में मैं पहले अनजान था।
शराबी

जवाबों:


110

int()0 के मान के साथ एक स्थिर अभिव्यक्ति है, इसलिए यह एक अशक्त सूचक स्थिरांक का एक वैध तरीका है। अंतत: यह कहने का तरीका थोड़ा अलग हैint *ptr = NULL;


3
+1, निरंतर अभिव्यक्ति बिट महत्वपूर्ण है और शीर्ष -2 उत्कीर्ण उत्तरों से गायब है।
डेविड रॉड्रिग्ज - drieaseas

क्या यह C ++ 0x के साथ चला जाता है?
नील जी

@ नील: यह सी ++ 11 में ही रहता है, हालांकि अब एक भी है nullptr, जिसे आप नए कोड में 0या उसके बजाय उपयोग कर सकते हैं NULL
जेरी कॉफिन

2
@ निल्स: कोड स्पष्टता और कोड के माध्यम से अपना इरादा घोषित करना। C ++ 11 के साथ, संभोग, अब आप nullptr का उपयोग करना चाहते हैं क्योंकि यह मिश्रण में अतिरिक्त संकलन-समय के लाभ को भी बढ़ाता है।
जमिन ग्रे

3
@ निल्स क्योंकि स्पष्ट रूप से 0एक शून्य सूचक स्थिरांक या संख्या 0 का अर्थ हो सकता है, जबकि nullptrस्पष्ट रूप से अशक्त सूचक स्थिरांक है। इसके अलावा, जैसा कि जामिन ने कहा, इसमें "अतिरिक्त संकलन-समय की जांच" भी है। टाइप करने से पहले सोचने की कोशिश करें।
माइल्स राउत

35

क्योंकि int()पैदावार 0, जो के साथ विनिमेय है NULLNULL0C के NULLजो है , के विपरीत ही परिभाषित किया गया है (void *) 0

ध्यान दें कि यह एक त्रुटि होगी:

int* ptr = int(5);

और यह अभी भी काम करेगा:

int* ptr = int(0);

0एक विशेष स्थिर मूल्य है और इसे एक पॉइंटर मूल्य के रूप में माना जा सकता है। लगातार अभिव्यक्ति, जो उपज देती हैं 0, जैसे 1 - 1कि शून्य-सूचक स्थिरांक की अनुमति है।


1
यह भी ध्यान दें कि C का NULL जरूरी नहीं है (void *)0। यह केवल एक कार्यान्वयन है जो "0 के साथ पूर्णांक स्थिर अभिव्यक्ति को परिभाषित करता है, या इस तरह की अभिव्यक्ति शून्य टाइप करने के लिए डाली जाती है"।
जेरी कॉफिन

@ जेरीकॉफिन मैंने कभी भी एक सी संकलक का उपयोग नहीं किया है जिसे परिभाषित किया NULLगया है (void*)0; यह हमेशा 0(या शायद 0L) था। (लेकिन, तब तक C90 ने (void*)0C में वैधानिक कर दिया था , मैं पहले से ही C ++ का उपयोग कर रहा था।)
जेम्स कांजे

1
@JamesKanze: ubuntu 11.04 में और हमारे अपने लिनक्स स्वाद में, libio.h शामिल है: #if !defined(__cplusplus) \n #define NULL ((void*)0) \n #else \n #define NULL (0)ubuntu में gcc का वर्तमान संस्करण 4.5 है, हमारी प्रणाली में 4.0 है।
डेविड रोड्रिगेज -

5
" 0एक विशेष शाब्दिक है" - केवल इसलिए कि यह एक स्थिर अभिव्यक्ति है, और इसका विशेष मान है 0. (1-1)समान रूप से विशेष है, यह एक अशक्त सूचक स्थिरांक भी है, और ऐसा ही है int()0शाब्दिक होने का तथ्य पर्याप्त है लेकिन स्थिर अभिव्यक्ति के लिए आवश्यक शर्त नहीं है। जैसे कुछ है strlen(""), हालांकि इसका विशेष मूल्य भी है 0, एक स्थिर अभिव्यक्ति नहीं है और इसलिए एक अशक्त सूचक स्थिर नहीं है।
स्टीव जेसप

@SteveJessop: मैं सुधार के बारे में सहमत हूं, यह वास्तव में निरंतर मूल्य के बारे में है 0, 0शाब्दिक नहीं ।
ब्लागोवेस्ट ब्युटुकलाइव

18

अभिव्यक्ति int()एक निरंतर डिफ़ॉल्ट-प्रारंभिक पूर्णांक का मूल्यांकन करती है, जो कि मान 0 है। वह मान विशेष है: इसका उपयोग NULL स्थिति में सूचक को प्रारंभ करने के लिए किया जाता है।


2
यह जेरी के उत्तर में मौजूद एक बहुत ही महत्वपूर्ण विवरण याद कर रहा है: यह पर्याप्त नहीं है कि अभिव्यक्ति का मूल्य 0 होता है, लेकिन यह भी एक स्थिर अभिव्यक्ति होना चाहिए । प्रति-उदाहरण के लिए, के साथ int f() { return 0; }, अभिव्यक्ति f()का मान 0 होता है, लेकिन इसका उपयोग सूचक को प्रारंभ करने के लिए नहीं किया जा सकता है।
डेविड रोड्रिगेज -

@ DavidRodríguez-dribeas, मेरे भाग में सबसे सरल संभव शब्दों में एक उत्तर प्रस्तुत करने के लिए मैंने उस भाग को छोड़ दिया। मुझे उम्मीद है कि अब यह स्वीकार्य है।
मार्क रैनसम

13

N3290 से (C ++ 03 समान पाठ का उपयोग करता है), 4.10 सूचक रूपांतरण [conv.ptr] पैराग्राफ 1 (जोर मेरा है):

1 अशक्त सूचक स्थिरांक पूर्णांक प्रकार का एक अभिन्न स्थिर अभिव्यक्ति (5.19) है जो शून्य या प्रकार के std :: nullptr_t के भाव का मूल्यांकन करता है । एक अशक्त सूचक स्थिरांक को एक सूचक प्रकार में परिवर्तित किया जा सकता है; परिणाम उस प्रकार का अशक्त सूचक मान है और ऑब्जेक्ट पॉइंटर या फ़ंक्शन पॉइंटर प्रकार के हर दूसरे मूल्य से अलग है। इस तरह के रूपांतरण को अशक्त सूचक रूपांतरण कहा जाता है। [...]

int()पूर्णांक प्रकार का ऐसा अभिन्न निरंतर अभिव्यक्ति है जो शून्य का मूल्यांकन करता है (यह एक कौर है!), और इस प्रकार एक पॉइंटर प्रकार को आरंभीकृत करने के लिए उपयोग किया जा सकता है। जैसा कि आप देख सकते हैं, 0एकमात्र अभिन्न अभिव्यक्ति नहीं है जो विशेष आवरण है।


4

वैसे int कोई वस्तु नहीं है।

मैं देख रहा हूँ कि यहाँ क्या हो रहा है आप int को बता रहे हैं * int द्वारा निर्धारित कुछ मेमोरी एड्रेस को इंगित करने के लिए ()

इसलिए यदि int () 0 बनाता है, तो int * मेमोरी एड्रेस 0 को इंगित करेगा


1
int()सबसे निश्चित रूप से एक वस्तु है।
ऑर्बिट

@Tomalak: मुझे नहीं लगता कि यह है। यह गैर-श्रेणी के प्रकार का अस्थायी है, और मुझे लगता है कि मैं यह कहने में सही हूं कि ये वस्तुएं नहीं हैं जहां तक ​​सी ++ मानक का संबंध है। यह थोड़ा अजीब है, हालांकि, "अस्थायी वस्तुओं" पर अनुभाग केवल वर्ग प्रकार के अस्थायी लोगों के बारे में सावधानीपूर्वक बात करना शुरू करता है, लेकिन बाद में यह बाध्यकारी संदर्भों के बारे में बात करता है, और निश्चित रूप से आप एक संदर्भ को बांध सकते हैं int()। परिभाषित करें int i;, तो कोई सवाल नहीं, iएक वस्तु है।
स्टीव जेसप

@Steve: मैं केवल इस पर बहस की उम्मीद करूंगा कि "ऑब्जेक्ट्स" C ++ में स्टोरेज का एक क्षेत्र है, और टेम्परेरीज़ में स्टोरेज, राइट नहीं है? 1.8 / 1 स्पष्ट रूप से अस्थायी लोगों की सूची नहीं देता है, लेकिन ऐसा लगता है जैसे कि उन्हें शामिल करने का इरादा है।
कक्षा

1
@Tomalak: हाँ वास्तव में, गैर-वर्ग प्रकार के अस्थायी लोगों को भंडारण की आवश्यकता नहीं है जब तक कि आप एक संदर्भ न लें। हालांकि कोई बात नहीं, यह ज्यादा मायने नहीं रखता। "अच्छी तरह से int एक वस्तु नहीं है" कथन केवल सत्य है क्योंकि intएक प्रकार है, एक वस्तु नहीं है। चाहे int()किसी वस्तु की पैदावार हो या सिर्फ एक प्रतिद्वंद्विता किसी को भी कहीं भी प्रभावित नहीं करती है।
स्टीव जेसप

@Steve: यह बहुत ही अप्राप्य है :)
ऑर्बिट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.