मेरे पास क्यों है ++; मैं--; एक दूसरे के ठीक बाद?


164

मैं 1997 में जारी किए गए nmap के स्रोत कोड को देख रहा था और मैंने कोड के इस खंड को देखा जो मुझे थोड़ा अजीब लगता है:

int i=0, j=0,start,end;
char *expr = strdup(origexpr);
ports = safe_malloc(65536 * sizeof(short));
i++;                                         /* <<<<<< */
i--;                                         /* <<<<<< */
for(;j < exlen; j++) 
  if (expr[j] != ' ') expr[i++] = expr[j]; 
expr[i] = '\0';

आप i++;और फिर i--;एक दूसरे के ठीक बाद क्यों होंगे ? iहै 0, फिर i++बदल जाता iहै 1। उसके बाद, i--मुड़ता iहै 0

मूल स्रोत कोड से लिंक करें। निम्न को खोजें:

i++;
i--;

क्या कोई समझा सकता है कि यह किस लिए है?


25
लेखक से पूछें ।
डेबलर

8
मुझे लगता है कि वे कुछ प्रयोगात्मक या डिबगिंग कोड का हिस्सा थे, जिसे लेखक बाद में निकालना भूल गया।
नाटे एल्ड्रेडज

6
कारण स्पष्ट रूप से आपको भ्रमित करने के लिए है, यही एकमात्र उद्देश्य है :-) एक छोटा सा मौका है कि यह कुछ प्राचीन संकलक में कुछ संकलक बग के आसपास काम करता है, उस स्थिति में हमें इस कारण बताने वाली टिप्पणी होनी चाहिए थी।
gnasher729

18
@ रिंगो: मस्ती के लिए मैंने इसे 1.27 gcc के साथ आज़माया, 1988 1988, godbolt पर: godbolt.org/z/yYyFrQ । (यह आधुनिक सिस्टम हेडर के साथ काम नहीं करता है, इसलिए मुझे सभी मानक पुस्तकालय कार्यों को स्वयं घोषित करना पड़ा।) लेकिन इसके साथ -Oही यह वास्तव में उन बयानों को अनुकूलित करता है।
नैट एल्ड्रेडगे

21
इसका मतलब प्रोग्रामर को लाइन द्वारा भुगतान किया गया था ...
टोनीके

जवाबों:


152

यह एक बग था। ये रेखाएँ एक साथ iअपरिवर्तित रहती हैं, इसलिए उन्हें वहाँ नहीं होना चाहिए था।

1 सितंबर 1997 को नैम्प को प्रस्तुत करने वाला लिंक लेख प्रकाशित किया गया था। यदि आप https://svn.nmap.org/nmap पर एसवीएन रिपॉजिटरी को नैम्प के लिए देखते हैं , तो 10 फरवरी 1998 को चेक किए गए प्रारंभिक संशोधन में वे पंक्तियाँ नहीं हैं:

int i=0, j=0,start,end;
char *expr = strdup(origexpr);
char *mem = expr;

ports = safe_malloc(65536 * sizeof(short));
for(;j < exlen; j++) 
  if (expr[j] != ' ') expr[i++] = expr[j]; 
expr[i] = '\0';

तो यह कुछ ऐसा है जो लेखक ने प्रारंभिक नैम्प सोर्स कोड और एसवीएन को प्रारंभिक चेकइन के प्रकाशन के बीच पाया और तय किया है।


1
हम्म वह पृष्ठ <pre>भी लेख के आसपास टैग गायब है; क्रोम के इंस्पेक्टर ने खुलासा किया कि डोम निर्माण के दौरान कुछ दस्तावेज कैसे बनते हैं?)
क्षुद्रग्रह विथ विंग्स

4
यह पाठकों को भ्रमित करता है, जो पूरी तरह से अनपेक्षित है। मैं कहूंगा कि यह स्पष्ट रूप से एक बग है। ;-)
सर्गट

2
@sergut विकिपीडिया आपके साथ सहमत नहीं है, लेकिन यह ब्लॉग पोस्ट करता है, और मैं इसके लिए इच्छुक हूं :-)
Toivo Säwén

4
अब अगर iकोई इंटक नहीं था, लेकिन ऑपरेटर ओवरलोड के साथ कुछ फैंसी क्लास, यह संभव है (हालांकि संभावना नहीं है और आमतौर पर खराब कोडिंग प्रथाओं का संकेत है) कि इसके कुछ दुष्प्रभाव हो सकते हैं। (केवल तभी लागू होता है यदि यह C ++ का हो।)
डारेल हॉफमैन

5
शायद ध्यान देने योग्य है कि कुछ संदर्भों (मेमोरी-मैप्ड IO) में, एक चर को बदलने से बाहरी प्रभाव हो सकते हैं।
nullromo

40

यह बेकार है। यह बिल्कुल कुछ भी नहीं करता है।

अगर मैं अनुमान लगाता कि शायद यह कुछ डिबगिंग कोड के अवशेष हैं जो विकास के दौरान उपयोग किए गए थे।

मेरा अनुमान है कि यह है कि दोनों में से किसी एक i++या i--एक परिवर्तन में पेश किया गया था और अन्य किसी अन्य रूप में पेश किया गया था।

मेरे पास परिचय का बिंदु खोजने का कोई तरीका नहीं है, हालाँकि, प्रारंभिक स्रोत रिलीज़ और पहले SVN संशोधन के बीच कोई संशोधन इतिहास नहीं था।


14
मुझे लगता है कि डिबगिंग कोड के बारे में अटकलें सटीक हैं। मैंने कई अलग-अलग प्रकार के डिबगिंग कोड देखे हैं, केवल ब्रेकपॉइंट्स प्राप्त करने के लिए जहां आप उनसे उम्मीद करते हैं।
नाथन गोह

9

गैर-अनुकूलन वाले कंपाइलर के लिए, या एक जो कि हार्डवेयर साइड इफेक्ट्स को मान्यता देता है, i ++; i-- अनुक्रम के कारण मैं मेमोरी से पढ़ा जा सकता है, फिर से लिखा जा सकता है, भले ही लूप के लिए उठाए गए रास्ते की परवाह किए बिना और नेस्टेड हो।

समानांतर प्रसंस्करण में, कभी-कभी कंपाइलर हैक को यह सुनिश्चित करने के लिए लिया जाता है कि कोड अनुक्रम वैश्विक प्रतियों के बजाय चर की अपनी स्थानीय प्रतियों का उपयोग करता है।

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

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


1
तो फिर इसे अस्थिर क्यों नहीं घोषित किया जाए?
vsz

6
iस्थानीय चर के रूप में घोषित करने को ऊपर दिए गए कोड में दिखाया गया है, और ऐसा कोई तरीका नहीं है जिससे i++; i--पंक्तियों के बिंदु पर किसी अन्य थ्रेड द्वारा पहुँचा जा सके ।
इंटरजेन

@vsz मुझे लगता है कि वह iगैर-वाष्पशील होने के लिए मजबूर है। मैंने C या C ++ में थ्रेडिंग से निपटा नहीं है, इसलिए मेरे पास कोई सुराग नहीं है कि इसे कैसे वाष्पशील माना जा सकता है और इसे कैसे i++; i--दबाया जाएगा।
ईगोर हंस

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

2

मैं आपको केवल अद्यतन कोड की जांच करने का सुझाव दूंगा। यदि आप इसके बाद (i = 2 + 1) का उपयोग करते हैं (i-1) जो कोई मतलब नहीं है। I का मान अपरिवर्तित रहता है। आप इसे किसी भी c या c ++ कंपाइलर का उपयोग करके आजमा सकते हैं। या यहां तक ​​कि किसी अन्य भाषा में भी ऐसा ही है। संकलक में कोड को देखें कि क्या मैं गलत या सही हूं, और मुझे बताएं कि क्या मैं गलत उत्तर दे रहा हूं।

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