सी में एक घोषित, गैर-पंजीकृत वैरिएबल का क्या होता है? क्या इसका कोई मूल्य है?


139

यदि CI में लिखें:

int num;

इससे पहले कि मैं कुछ भी असाइन करूं num, क्या numअनिश्चितता का मूल्य है ?


4
उम, यह एक परिभाषित चर नहीं है, एक घोषित नहीं है ? (मुझे खेद है कि अगर मेरा C ++ चमक रहा है ...)
sbi

6
नहीं। मैं इसे परिभाषित किए बिना एक चर घोषित कर सकता हूं: extern int x;हालांकि परिभाषित करने का अर्थ है हमेशा घोषणा करना। यह सी ++ में सच नहीं है, स्थिर वर्ग के सदस्य चर के साथ घोषित किए बिना परिभाषित कर सकते हैं, क्योंकि घोषणा कक्षा की परिभाषा में होनी चाहिए (घोषणा नहीं!) और परिभाषा कक्षा की परिभाषा के बाहर होनी चाहिए।
21

ee.hawaii.edu/~tep/EE160/Book/chap14/subsection2.1.1.4.html परिभाषित लगता है कि आपको इसे शुरू करना है, भी।
atp

जवाबों:


188

स्टेटिक चर (फ़ाइल स्कोप और फंक्शन स्टेटिक) शून्य से आरंभिक होते हैं:

int x; // zero
int y = 0; // also zero

void foo() {
    static int x; // also zero
}

गैर-स्थिर चर (स्थानीय चर) अनिश्चित होते हैं । अपरिभाषित व्यवहार में मूल्य परिणाम निर्दिष्ट करने से पहले उन्हें पढ़ना।

void foo() {
    int x;
    printf("%d", x); // the compiler is free to crash here
}

व्यवहार में, वे शुरू में सिर्फ कुछ निरर्थक मूल्य रखते हैं - कुछ संकलक विशिष्ट, निश्चित मानों में भी डाल सकते हैं, जब डिबगर में देख रहे हैं, तो यह स्पष्ट करने के लिए - लेकिन कड़ाई से बोलते हुए, संकलक दुर्घटनाग्रस्त से कुछ भी करने के लिए स्वतंत्र है अपने नाक मार्ग के माध्यम से राक्षसों

क्योंकि यह केवल "अपरिभाषित / मनमाना मूल्य" के बजाय अपरिभाषित व्यवहार है, ऐसे कई सीपीयू आर्किटेक्चर हैं जिनके पास विभिन्न प्रकारों के लिए उनके प्रतिनिधित्व में अतिरिक्त ध्वज बिट्स हैं। एक आधुनिक उदाहरण इटेनियम होगा, जिसके रजिस्टरों में "नॉट ए थिंग" बिट है ; बेशक, सी मानक ड्राफ्टर्स कुछ पुराने आर्किटेक्चर पर विचार कर रहे थे।

इन ध्वज बिट्स सेट के साथ एक मान के साथ काम करने का प्रयास करने से सीपीयू अपवाद हो सकता है एक ऑपरेशन में जो वास्तव में विफल नहीं होना चाहिए (जैसे, पूर्णांक जोड़, या किसी अन्य चर को असाइन करना)। और अगर आप एक चर को छोड़ते हैं, तो संकलक इन फ्लैग बिट्स सेट के साथ कुछ यादृच्छिक कचरा उठा सकता है - जिसका अर्थ है कि अनैतिक रूप से परिवर्तित चर घातक हो सकता है।


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

8
क्या नहीं है मानक द्वारा स्थैतिक आरंभ की आवश्यकता होती है; आईएसओ / आईईसी 9899 देखें: 1999 6.7.8 # 10
21

2
पहला उदाहरण ठीक है जहां तक ​​मैं बता सकता हूं। मैं कम क्यों कर रहा हूँ क्यों संकलक हालांकि दूसरे में दुर्घटनाग्रस्त हो सकता है :)

6
@ स्टुअर्ट: "ट्रैप प्रतिनिधित्व" नामक एक चीज है, जो मूल रूप से एक बिट पैटर्न है जो एक वैध मूल्य को निरूपित नहीं करता है, और रनटाइम पर उदाहरण के लिए हार्डवेयर अपवाद हो सकता है। एकमात्र सी प्रकार जिसके लिए कोई गारंटी है कि कोई भी बिट पैटर्न एक वैध मूल्य है char; अन्य सभी में ट्रैप अभ्यावेदन हो सकते हैं। वैकल्पिक रूप से - चूंकि असंबद्ध वैरिएबल एक्सेस करना यूबी वैसे भी है - एक कंफर्मिंग कंपाइलर बस कुछ चेकिंग कर सकता है और समस्या का संकेत देने का निर्णय ले सकता है।
पावेल मिनाएव

5
बडोनियन सही है। सी को हमेशा काफी सटीक रूप से निर्दिष्ट किया गया है। C89 और C99 से पहले, dmr के एक पेपर ने 1970 के दशक की शुरुआत में इन सभी चीजों को निर्दिष्ट किया था। यहां तक ​​कि crudest एम्बेडेड सिस्टम में, चीजों को सही करने के लिए केवल एक मेमसेट () लेता है, इसलिए गैर-अनुरूप वातावरण के लिए कोई बहाना नहीं है। मैंने अपने उत्तर में मानक का हवाला दिया है।
DigitalRoss

57

0 यदि स्थैतिक या वैश्विक, अनिश्चित है यदि भंडारण वर्ग ऑटो है

C हमेशा वस्तुओं के प्रारंभिक मूल्यों के बारे में बहुत विशिष्ट रहा है। यदि वैश्विक या static, वे शून्य हो जाएगा। यदि auto, मान अनिश्चित है

यह पूर्व-C89 संकलक में मामला था और K & R द्वारा और DMR की मूल C रिपोर्ट में निर्दिष्ट किया गया था।

C89 में यह मामला था, खंड 6.5.7 प्रारंभिक देखें ।

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

C99 में यह मामला था, खंड 6.7.8 प्रारंभिक देखें ।

यदि किसी ऑब्जेक्ट में स्वचालित भंडारण अवधि है, तो उसे स्पष्ट रूप से प्रारंभ नहीं किया गया है, इसका मूल्य अनिश्चित है। यदि किसी ऑब्जेक्ट में स्थिर भंडारण अवधि स्पष्ट रूप से प्रारंभ नहीं की गई है, तो:
- यदि इसमें पॉइंटर प्रकार है, तो इसे एक नल पॉइंटर के लिए आरंभीकृत किया जाता है;
- अगर इसमें अंकगणित प्रकार है, तो इसे (सकारात्मक या अहस्ताक्षरित) शून्य पर आरंभीकृत किया जाता है;
- यदि यह एक समग्र है, तो प्रत्येक सदस्य इन नियमों के अनुसार आरंभीकृत (पुनरावर्ती) होता है;
- यदि यह एक संघ है, तो पहले नामित सदस्य को इन नियमों के अनुसार आरंभीकृत (पुनरावर्ती) किया जाता है।

जैसा कि वास्तव में अनिश्चितता का मतलब है, मुझे C89 के लिए यकीन नहीं है, C99 कहते हैं:

3.17.2
अनिश्चित मान

या तो अनिर्दिष्ट मूल्य या जाल प्रतिनिधित्व है

लेकिन वास्तविक जीवन में, मानकों का कहना है कि परवाह किए बिना, प्रत्येक स्टैक पेज वास्तव में शून्य के रूप में शुरू होता है, लेकिन जब आपका प्रोग्राम किसी भी autoभंडारण वर्ग के मूल्यों को देखता है, तो यह देखता है कि आपके खुद के प्रोग्राम द्वारा पीछे छोड़ दिया गया था जब उसने उन स्टैक पतों का उपयोग किया था। यदि आप बहुत सारे autoसरणियाँ आवंटित करते हैं, तो आप उन्हें अंततः शून्य से बड़े करीने से देखेंगे।

आप आश्चर्यचकित हो सकते हैं, ऐसा क्यों है? एक अलग SO उत्तर उस प्रश्न से संबंधित है, देखें: https://stackoverflow.com/a/2091505/140740


3
आमतौर पर अनिश्चित (इस्तेमाल किया जाता है?) इसका मतलब है कि यह कुछ भी कर सकता है। यह शून्य हो सकता है, यह मूल्य हो सकता है जो वहां था, यह प्रोग्राम को क्रैश कर सकता है, यह कंप्यूटर को सीडी स्लॉट से बाहर ब्लूबेरी पेनकेक्स का उत्पादन कर सकता है। आपकी कोई गारंटी नहीं है। यह ग्रह के विनाश का कारण हो सकता है। कम से कम जहां तक ​​कल्पना जाती है ... किसी ने भी एक कंपाइलर बनाया जो वास्तव में ऐसा कुछ भी करता था वह बी- पर बहुत
डूब जाएगा

C11 N1570 ड्राफ्ट में, 3.19.2 पर परिभाषा प्राप्त की indeterminate valueजा सकती है।
user3528438

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

1
@ आदित्यसिंह, ओएस संकलक पर आसान बना सकता है , लेकिन अंततः यह संकलक की प्राथमिक जिम्मेदारी है कि वह दुनिया की मौजूदा सूची C कोड को चलाए, और मानकों को पूरा करने के लिए एक माध्यमिक जिम्मेदारी है। यह निश्चित रूप से अलग तरीके से करना संभव होगा , लेकिन, क्यों? इसके अलावा, स्थैतिक डेटा को अनिश्चित बनाने के लिए यह मुश्किल है, क्योंकि ओएस वास्तव में सुरक्षा कारणों से पहले पृष्ठों को शून्य करना चाहेगा। (ऑटो चर केवल सतही अप्रत्याशित हैं क्योंकि आपका खुद का कार्यक्रम आमतौर पर उन पुराने पतों का उपयोग पहले बिंदु पर करता रहा है।)
DigitalRoss

@BrianPostow नहीं, यह सही नहीं है। Stackoverflow.com/a/40674888/584518 देखें । अनिश्चित मान का उपयोग अनिर्दिष्ट व्यवहार का कारण बनता है, अपरिभाषित व्यवहार नहीं, ट्रैप अभ्यावेदन के मामले के लिए बचाएं।
लुंडिन

12

यह चर की भंडारण अवधि पर निर्भर करता है। स्थिर भंडारण अवधि वाला एक चर हमेशा शून्य के साथ अंतर्निहित होता है।

स्वचालित (स्थानीय) चरों के लिए, एक अनियंत्रित चर का अनिश्चित मान होता है । अन्य बातों के अलावा, अनिश्चित मान का मतलब है कि उस चर में जो भी "मूल्य" आप "देख" सकते हैं, वह न केवल अप्रत्याशित है, बल्कि स्थिर होने की गारंटी भी नहीं है । उदाहरण के लिए, व्यवहार में (यानी एक सेकंड के लिए यूबी की अनदेखी) यह कोड

int num;
int a = num;
int b = num;

चर की गारंटी नहीं है aऔर bसमान मूल्यों को प्राप्त होगा। दिलचस्प बात यह है कि यह कुछ पांडित्यपूर्ण सैद्धांतिक अवधारणा नहीं है, यह आसानी से अनुकूलन के परिणाम के रूप में होता है।

तो सामान्य तौर पर, लोकप्रिय जवाब कि "यह कचरा के साथ शुरू होता है जो कि स्मृति में था" भी दूर से सही नहीं है। Uninitialized चर का व्यवहार कचरा के साथ आरंभिक चर से भिन्न होता है ।


मैं समझ नहीं पा रहा हूं (अच्छी तरह से मैं बहुत अच्छी तरह से ) क्यों कर सकते हैं यह DigitalRoss से एक मिनट के बाद की तुलना में बहुत कम है: D
Antti Haapala

7

Ubuntu 15.10, कर्नेल 4.2.0, x86-64, GCC 5.2.1 उदाहरण

पर्याप्त मानकों, चलो एक कार्यान्वयन को देखो :-)

स्थानीय चर

मानक: अपरिभाषित व्यवहार।

कार्यान्वयन: कार्यक्रम स्टैक स्थान आवंटित करता है, और कभी भी उस पते पर कुछ भी नहीं ले जाता है, इसलिए जो कुछ भी पहले था उसका उपयोग किया जाता है।

#include <stdio.h>
int main() {
    int i;
    printf("%d\n", i);
}

संकलन:

gcc -O0 -std=c99 a.c

आउटपुट:

0

और साथ विघटित:

objdump -dr a.out

सेवा:

0000000000400536 <main>:
  400536:       55                      push   %rbp
  400537:       48 89 e5                mov    %rsp,%rbp
  40053a:       48 83 ec 10             sub    $0x10,%rsp
  40053e:       8b 45 fc                mov    -0x4(%rbp),%eax
  400541:       89 c6                   mov    %eax,%esi
  400543:       bf e4 05 40 00          mov    $0x4005e4,%edi
  400548:       b8 00 00 00 00          mov    $0x0,%eax
  40054d:       e8 be fe ff ff          callq  400410 <printf@plt>
  400552:       b8 00 00 00 00          mov    $0x0,%eax
  400557:       c9                      leaveq
  400558:       c3                      retq

X86-64 कॉलिंग कन्वेंशन के हमारे ज्ञान से:

  • %rdiपहला प्रिंटफ तर्क है, इस प्रकार "%d\n"पते पर स्ट्रिंग0x4005e4

  • %rsiइस प्रकार दूसरा प्रिंटफ तर्क है i

    यह आता है -0x4(%rbp), जो पहले 4-बाइट स्थानीय चर है।

    इस बिंदु पर, rbpस्टैक के पहले पृष्ठ में कर्नेल द्वारा आवंटित किया गया है, इसलिए उस मूल्य को समझने के लिए हमें कर्नेल कोड को देखना होगा और यह पता लगाना होगा कि यह किसके लिए सेट है।

    TODO क्या कर्नेल उस मेमोरी को किसी अन्य प्रक्रिया के लिए पुन: उपयोग करने से पहले सेट करता है जब कोई प्रक्रिया मर जाती है? यदि नहीं, तो नई प्रक्रिया डेटा को लीक करते हुए अन्य तैयार कार्यक्रमों की मेमोरी को पढ़ने में सक्षम होगी। देखें: क्या अनैतिक रूप से मूल्य कभी सुरक्षा जोखिम हैं?

फिर हम अपने स्वयं के स्टैक संशोधनों के साथ भी खेल सकते हैं और मजेदार चीजें लिख सकते हैं जैसे:

#include <assert.h>

int f() {
    int i = 13;
    return i;
}

int g() {
    int i;
    return i;
}

int main() {
    f();
    assert(g() == 13);
}

में स्थानीय चर -O3

पर कार्यान्वयन विश्लेषण: क्या करता है <मूल्य बाहर अनुकूलित> जीडीबी में मतलब है?

सार्वत्रिक चर

मानक: 0

कार्यान्वयन: .bssअनुभाग।

#include <stdio.h>
int i;
int main() {
    printf("%d\n", i);
}

gcc -00 -std=c99 a.c

के लिए संकलन:

0000000000400536 <main>:
  400536:       55                      push   %rbp
  400537:       48 89 e5                mov    %rsp,%rbp
  40053a:       8b 05 04 0b 20 00       mov    0x200b04(%rip),%eax        # 601044 <i>
  400540:       89 c6                   mov    %eax,%esi
  400542:       bf e4 05 40 00          mov    $0x4005e4,%edi
  400547:       b8 00 00 00 00          mov    $0x0,%eax
  40054c:       e8 bf fe ff ff          callq  400410 <printf@plt>
  400551:       b8 00 00 00 00          mov    $0x0,%eax
  400556:       5d                      pop    %rbp
  400557:       c3                      retq
  400558:       0f 1f 84 00 00 00 00    nopl   0x0(%rax,%rax,1)
  40055f:       00

# 601044 <i>कहते हैं कि iपते पर है 0x601044और:

readelf -SW a.out

शामिल हैं:

[25] .bss              NOBITS          0000000000601040 001040 000008 00  WA  0   0  4

जो कहता 0x601044है कि .bssअनुभाग के मध्य में सही है , जो शुरू होता है 0x601040और 8 बाइट लंबा होता है।

ELF मानक तो गारंटी देता है कि नामित अनुभाग .bssपूरी तरह से शून्य की से भर जाता है:

.bssयह खंड अनइंस्टाल्यूटेड डेटा रखता है जो प्रोग्राम की मेमोरी इमेज में योगदान देता है। परिभाषा के अनुसार, प्रोग्राम शुरू होने पर सिस्टम शून्य के साथ डेटा को इनिशियलाइज़ करता है। अनुभाग, के रूप में अनुभाग इस प्रकार से संकेत दिया, कचौड़ी occu- कोई फ़ाइल अंतरिक्ष SHT_NOBITS

इसके अलावा, प्रकार SHT_NOBITSकुशल है और निष्पादन योग्य फ़ाइल पर कोई स्थान नहीं लेता है:

sh_sizeयह सदस्य बाइट में अनुभाग का आकार देता है। जब तक sec- tion टाइप नहीं होता है SHT_NOBITS, तब तक sh_size फाइल में सेक्शन बाइट्स पर रहता है। प्रकार के एक खंड में SHT_NOBITSएक गैर-शून्य आकार हो सकता है, लेकिन यह फ़ाइल में कोई स्थान नहीं रखता है।

फिर यह लिनक्स कर्नेल पर निर्भर है कि प्रोग्राम को लोड करने पर उस मेमोरी क्षेत्र को शून्य कर दिया जाए जब यह शुरू हो जाता है।


4

वह निर्भर करता है। यदि वह परिभाषा वैश्विक है (किसी भी कार्य के बाहर) तो numउसे शून्य से आरंभ किया जाएगा। यदि यह स्थानीय है (किसी कार्य के अंदर) तो इसका मूल्य अनिश्चित है। सिद्धांत रूप में, यहां तक ​​कि मूल्य को पढ़ने के प्रयास में अपरिभाषित व्यवहार होता है - C उन बिट्स की संभावना के लिए अनुमति देता है जो मूल्य में योगदान नहीं करते हैं, लेकिन आपको चर को पढ़ने से परिभाषित परिणाम प्राप्त करने के लिए विशिष्ट तरीके से सेट करना होगा।


1

क्योंकि कंप्यूटरों में भंडारण क्षमता कम होती है, इसलिए स्वचालित चर आमतौर पर भंडारण तत्वों (चाहे रजिस्टर या रैम) में रखे जाएंगे जो पहले किसी अन्य मनमाने उद्देश्य के लिए उपयोग किए गए हों। यदि इस तरह के एक चर का उपयोग किसी मूल्य को सौंपे जाने से पहले किया जाता है, तो यह भंडारण जो कुछ भी पहले रखता है, उसे पकड़ सकता है, और इसलिए चर की सामग्री अप्रत्याशित होगी।

अतिरिक्त शिकन के रूप में, कई कंपाइलर रजिस्टरों में वैरिएबल रख सकते हैं जो संबद्ध प्रकारों से बड़े होते हैं। हालाँकि यह सुनिश्चित करने के लिए एक कंपाइलर की आवश्यकता होगी कि कोई भी मान जो एक वैरिएबल को लिखा जाए और वापस पढ़ा जाए, को छोटा किया जाएगा और / या उसके उचित आकार में साइन-एक्सटेंड किया जाएगा, कई कंपाइलर ऐसे ट्रंकेशन का प्रदर्शन करेंगे, जब वेरिएबल लिखे जाएंगे और उम्मीद करेंगे कि यह होगा चर को पढ़ने से पहले किया जाता है। ऐसे कंपाइलरों पर, कुछ इस तरह:

uint16_t hey(uint32_t x, uint32_t mode)
{ uint16_t q; 
  if (mode==1) q=2; 
  if (mode==3) q=4; 
  return q; }

 uint32_t wow(uint32_t mode) {
   return hey(1234567, mode);
 }

wow()क्रमशः 1234567 मूल्यों को 0 और 1, क्रमशः और कॉलिंग में संग्रहीत करने में बहुत अच्छी तरह से परिणाम हो सकता है foo()। चूंकि x"फू" की आवश्यकता नहीं है, और चूंकि फ़ंक्शन को उनके रिटर्न मान को रजिस्टर 0 में रखना है, इसलिए कंपाइलर को 0 से रजिस्टर आवंटित किया जा सकता है q। यदि mode1 या 3 है, तो रजिस्टर 0 क्रमशः 2 या 4 के साथ लोड किया जाएगा, लेकिन अगर यह कुछ अन्य मूल्य है, तो फ़ंक्शन 0 में जो कुछ भी था (यानी 1234567) मान वापस आ सकता है, भले ही वह मूल्य सीमा के भीतर न हो uint16_t की

यह सुनिश्चित करने के लिए अतिरिक्त काम करने के लिए संकलक की आवश्यकता से बचने के लिए कि असिंचित चर उनके डोमेन के बाहर के मानों को कभी भी धारण नहीं करते हैं, और अत्यधिक विस्तार से अनिश्चित व्यवहार को निर्दिष्ट करने की आवश्यकता से बचने के लिए, मानक कहते हैं कि असिंचित स्वचालित चर का उपयोग अनिर्धारित व्यवहार है। कुछ मामलों में, इसके प्रकार की सीमा के बाहर मूल्य होने की तुलना में इसके परिणाम और भी आश्चर्यजनक हो सकते हैं। उदाहरण के लिए, दिया गया:

void moo(int mode)
{
  if (mode < 5)
    launch_nukes();
  hey(0, mode);      
}

एक कंपाइलर यह अनुमान लगा सकता है कि क्योंकि moo()एक मोड जो कि 3 से अधिक है के साथ इनवॉइस करने के लिए अपरिभाषित व्यवहार को लागू करने के लिए अनिवार्य रूप से कार्यक्रम का नेतृत्व करेगा, कंपाइलर किसी भी कोड को छोड़ सकता है जो केवल mode4 या अधिक से अधिक प्रासंगिक होगा , जैसे कि कोड जो सामान्य रूप से रोक देगा। ऐसे मामलों में nukes का शुभारंभ। ध्यान दें कि न तो मानक, न ही आधुनिक संकलक दर्शन, इस तथ्य की परवाह करेंगे कि "हे" से वापसी मूल्य को अनदेखा किया गया है - इसे वापस करने की कोशिश करने का कार्य मनमाना कोड उत्पन्न करने के लिए एक संकलित असीमित लाइसेंस देता है।


0

मूल उत्तर है, हां यह अपरिभाषित है।

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


0

यदि संग्रहण वर्ग स्थिर या वैश्विक है, तो लोडिंग के दौरान, BSS चर या मेमोरी लोकेशन (ML) को 0 तक प्रारंभ करता है, जब तक कि चर को शुरू में कुछ मान नहीं दिया जाता है। स्थानीय असंगठित चर के मामले में ट्रैप प्रतिनिधित्व स्मृति स्थान को सौंपा गया है। इसलिए यदि आपका कोई रजिस्टर जिसमें महत्वपूर्ण जानकारी हो, कंपाइलर द्वारा ओवरराइट किया जाता है, तो प्रोग्राम क्रैश हो सकता है।

लेकिन ऐसी समस्या से बचने के लिए कुछ कंपाइलरों में तंत्र हो सकता है।

मैं nec v850 श्रृंखला के साथ काम कर रहा था जब मुझे महसूस हुआ कि ट्रैप प्रतिनिधित्व है जिसमें बिट पैटर्न हैं जो डेटा के प्रकारों के लिए अपरिभाषित मूल्यों का प्रतिनिधित्व करते हैं, चार को छोड़कर। जब मैंने एक असंवैधानिक चार्ट लिया तो मुझे ट्रैप प्रतिनिधित्व के कारण शून्य डिफ़ॉल्ट मान मिला। यह necv850es का उपयोग करके किसी भी 1 के लिए उपयोगी हो सकता है


यदि अहस्ताक्षरित चार का उपयोग करते हुए आप ट्रैप अभ्यावेदन प्राप्त करते हैं तो आपका सिस्टम आज्ञाकारी नहीं है। उन्हें स्पष्ट रूप से ट्रैप अभ्यावेदन, C17 6.2.6.1/5 शामिल करने की अनुमति नहीं है।
लुंडिन

-2

मूल्य का मान मुख्य मेमोरी (RAM) से कुछ कचरा मूल्य होगा। यह बेहतर है अगर आप केवल बनाने के बाद चर को इनिशियलाइज़ करते हैं।


-4

जहाँ तक मैं चला गया था यह ज्यादातर संकलक पर निर्भर है, लेकिन सामान्य रूप से अधिकांश मामलों में मान को पूर्ववर्ती द्वारा 0 के रूप में माना जाता है।
मुझे कुलपति ++ के मामले में कचरा मूल्य मिला, जबकि टीसी ने मूल्य 0. दिया। मैंने इसे नीचे की तरह प्रिंट किया

int i;
printf('%d',i);

यदि आपको उदाहरण के लिए एक निर्धारक मूल्य प्राप्त होता है, तो 0आपके संकलक के लिए यह सुनिश्चित करने के लिए अतिरिक्त कदम बढ़ जाता है कि यह उस मूल्य को प्राप्त करता है (वैसे भी चर को आरंभ करने के लिए कोड जोड़कर)। "डीबग" संकलन करते समय कुछ कंपाइलर ऐसा करते हैं, लेकिन 0इनके लिए मूल्य चुनना एक बुरा विचार है क्योंकि यह आपके कोड में दोष छिपाएगा (अधिक उचित बात यह है कि वास्तव में असंभावित संख्या जैसे 0xBAADF00Dया कुछ समान की गारंटी देने के लिए )। मुझे लगता है कि अधिकांश संकलक बस उस कूड़े को छोड़ देंगे जो कि चर के मान के रूप में मेमोरी पर कब्जा करने के लिए होता है (यानी यह सामान्य रूप से मान लिया नहीं जाता है 0)।
आसमान छू रहा है
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.