9

this Code Golf post में, वहाँ का दावा है कि "एक परिभाषा में दूसरा चर हमेशा 1 पर सेट है", यह एक अच्छी तरह से गठित लाइन बना रही है:क्या एकाधिक घोषणा में दूसरा int हमेशा 1 पर सेट होता है?

int i=-1,c,o,w,b,e=b=w=o=c; 

और माना जाता है कि i के अलावा सब कुछ 1 पर सेट है क्योंकि c स्वचालित रूप से 1.

मैंने सोचा कि मुझे कुछ सी पता था, और सोचा कि यह अवैध था (यूबी होने और परिणामस्वरूप यादृच्छिक ढेर सामग्री में कुछ भी)।

क्या सी वास्तव में c से 1 सेट करता है?

+1

मैं वास्तव में इस नहीं मिलता है, 'c' अप्रारंभीकृत चर के आराम करने के लिए असाइन किया गया है हर किसी के इनपुट के लिए

धन्यवाद, मैं गलत हो सकता है लेकिन यह अपरिभाषित व्यवहार लगता है। –

+3

[इस] के अनुसार (http://meta.codegolf.stackexchange.com/questions/5486/is-an-answer-allowed-to-use-undefined-but-consistent-behaviour), निरंतर, अपरिभाषित व्यवहार ठीक है कोड गोल्फिंग के लिए, तो शायद कार्यक्रम के निर्माता ने इसका शोषण किया। – Downvoter

+0

यदि 'i' में स्वचालित संग्रहण अवधि है, तो यह अच्छी तरह से बनाई गई है। यदि यह स्थिर भंडारण अवधि है, तो यह विकृत है क्योंकि चर को प्रारंभ करने के लिए निरंतर अभिव्यक्तियों की आवश्यकता होती है। – Downvoter

उत्तर

5

मैं कोडगॉल्फ से ओपी हूं। ऐसा लगता है कि मेरे पास बस एक टाइपो था, मेरा मतलब था int i=-1,c,o,w,b,e=b=w=o=c=1; इस तरह दूसरा परिभाषित int हमेशा 1 पर सेट होता है और अन्य इसे सेट कर सकते हैं। भ्रम यह है कि मेरे पास मूल रूप से वेरिएबल था जो अगले (एल = 3) के रूप में आता है जैसे कि एल (अपरिभाषित) और मैं अन्य सभी चर सेट कर रहा था e = b = w = o = c = (एल = 3); जो मेरे दिमाग में एल बराबर 3 सेट करने जा रहा था, उस (1) के लिए सच हो गया, फिर बाकी को सेट करें 1.

कुछ परीक्षण बाद में मुझे एहसास हुआ कि यह सिर्फ उन्हें 3 पर सेट कर रहा था और केवल साथ ही काम किया विशिष्ट स्ट्रिंग जो मैं अपने कोड का परीक्षण करने के लिए उपयोग कर रहा था। तो मैंने उन्हें हटा दिया और इसे एल = 3 हार्ड कोडित करने के लिए बदल दिया और अन्य e=b=w=o=c=1;L=3 होने के लिए बदल गए। किसी बिंदु पर मैंने cmd + z को कई बार दबाया होगा और "=" और "1" को हटा दिया होगा, इसलिए मुझे e=b=w=o=c; के साथ छोड़ दिया गया था। इसकी निरंतर अनिर्धारित प्रकृति के कारण (कम से कम मेरे आईडीई पर) यह हमेशा उन्हें 0 के रूप में परिभाषित करता था और इसके लिए बग अनदेखा हुआ था।

अब जब मैंने इसे वापस सही किया है, तो इस पोस्ट के लिए धन्यवाद, बाइट लंबाई समान है और किसी भी मुश्किल e=b=w=o=c=1 कोड के लिए किसी भी आवश्यकता की आवश्यकता नहीं थी, मैंने केवल सोचा था कि बाइट लंबाई अलग थी क्योंकि जब मैं प्रतिलिपि करता हूं मेरे कार्य को बाइट काउंटर में चिपकाया, यह दिखाता है कि यह 2 बाइट छोटे था (मुझे नहीं पता था कि मेरे पास सिर्फ एक टाइपो था और 2 बाइट्स गायब था)।

मेरा आईडीई हमेशा उन चरों को 0 के रूप में परिभाषित कर रहा है। मेरा कोड 1 के रूप में परिभाषित सभी चर के साथ काम करने के लिए डिज़ाइन किया गया है, यह तथ्य कि यह काम करता है w/0 संयोग है। इसके अलावा, क्योंकि यह मेरे आईडीई पर होता है इसका मतलब यह नहीं है कि यह दूसरों पर होगा, हालांकि मैंने इसे कुछ आईडीई पर ऑनलाइन परीक्षण किया है और कई लूप चलाए हैं और ऐसा लगता है कि हमेशा वापसी 0 है। किसी भी घटना में, मेरे पास है अभी भी मेरे मूल कोड को 1 पर सेट करने के लिए अपडेट किया गया है क्योंकि यह होना चाहिए (मेरे प्रोग्राम में 2 बाइट जोड़ना)।

+3

इस तरह के प्रश्नों के साथ आप "यह यूबी है, जिसने इस कोड को मानक सी ++ की वेदी पर लिखा है उसे जलाएं" या "यह एक अद्भुत चाल है, जो सी ++ के अंधेरे कोने को प्रकट करता है"। और फिर आप आए और "हाय दोस्तों, जैसे ... हाँ, मैंने सीटीआरएल-जेड गलती की ..." जो ... बहुत anticlimactic है ... ओह ठीक है। ऐसा होता है :) – bolov

5

यह कोड undefined behavior प्रदर्शित करता है।

चर c, o, b, और w अनियमित हैं। इसका मतलब है कि उनकी सामग्री अनिश्चित हैं।

C standard की धारा 6.7.9 से:

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

c का अनिश्चित मूल्य कई अन्य चरों को सौंपा गया है। एक अनियमित चर के मान को पढ़कर, कोड अपरिभाषित व्यवहार का आह्वान करता है।

cका प्रारंभिक मूल्य 1 हो सकता है, लेकिन यदि ऐसा है तो यह अनुमानित मूल्य नहीं है।

भी ध्यान रखें कि उपरोक्त कथन है, इसलिए इस बयान (c, o, b, और w के लिए) फ़ाइल दायरे में संकलन नहीं होगा दोनों आरंभीकरण और असाइनमेंट (i और e के लिए) शामिल हैं।

मैंने लिंक किए गए पोस्ट में फ़ंक्शन चलाने का प्रयास किया और यह पहला टेस्ट इनपुट पास नहीं हुआ। अपरिभाषित व्यवहार।

2

वहाँ सी मानक में ऐसी कोई जादू नियम, दूसरी int वस्तु 1 साथ स्थापित किया जाना है। वास्तव में, मूल्य अनिश्चित है, इस मामले में कोड बिना शर्त यूबी का आह्वान करता है।

C11 § 6.3.2.1/2 Lvalues, सरणियों, और समारोह designators

lvalue स्वत: भंडारण अवधि का एक उद्देश्य हो सकता है कि register भंडारण वर्ग के साथ घोषित किया गया है निर्दिष्ट करता है (कभी नहीं इसका पता लिया गया है), और वह ऑब्जेक्ट अनियमित है (प्रारंभकर्ता के साथ घोषित नहीं किया गया है और इसका उपयोग करने के लिए पहले का उपयोग करने के लिए कोई असाइनमेंट नहीं किया गया है), व्यवहार अपरिभाषित है।

लेकिन आइए किसी अन्य क्षण के लिए अन्यथा मान लें। जीसीसी 6 पर x86-64 आर्किटेक्चर के लिए जेनरेट की गई केवल एक उदाहरण असेंबली है।3, बदल गया बंद अनुकूलन, SysV ABI बुला सम्मेलनों:

mov  DWORD PTR [rbp-4], -1 
    mov  eax, DWORD PTR [rbp-8]  ; ??? 
    mov  DWORD PTR [rbp-12], eax 
    mov  eax, DWORD PTR [rbp-12] 
    mov  DWORD PTR [rbp-16], eax 
    mov  eax, DWORD PTR [rbp-16] 
    mov  DWORD PTR [rbp-20], eax 
    mov  eax, DWORD PTR [rbp-20] 
    mov  DWORD PTR [rbp-24], eax 

जहाँ तक, के रूप में संकलक का संबंध है, वहाँ न तो कोई गारंटी नहीं है। परिवर्तनीय c वर्तमान स्टैक फ्रेम पर RBP-8 ऑफ़सेट पर स्थित है। इसका प्रारंभिक मान है जो पहले स्टैक पर रखा गया था।

+1

यह अपरिभाषित व्यवहार की _one_ संभावना है। लेकिन यह अपरिभाषित है, इसलिए आपका प्रोग्राम क्रैश हो सकता है, या सभी चर अलग-अलग मानों पर सेट हो जाते हैं, या सभी चर आपके प्रोग्राम में बाद में अधिक मजेदार के साथ अपरिभाषित रहते हैं। – gnasher729

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