सी
यह मुझे एक त्रुटि की याद दिलाता है जब मैंने सी। सीखा था। मूल रूप से मूल संस्करण वर्तमान जीसीसी के साथ काम नहीं करता है, लेकिन यह अभी भी करता है:
#define ARR_SIZE 1234
int main() {
int i = ARR_SIZE;
int arr[ARR_SIZE];
while(i >= 0) {
(--i)[arr] = 0;
}
i = *(int*)0;
}
यह स्पष्ट रूप से segfaults है क्योंकि हम एक अशक्त सूचक को सही मानते हैं?
गलत - वास्तव में, यह एक अनंत लूप है क्योंकि हमारी लूप स्थिति एक के बाद एक बंद है। उपसर्ग घटने के कारण, i
1023 से -1 तक चलता है। इसका मतलब यह है कि असाइनमेंट न केवल सभी तत्वों को अधिलेखित करता है arr
, बल्कि इससे पहले कि यह सीधे मेमोरी स्थान है - जो उस स्थान पर होता है जहां i
संग्रहीत होता है। पहुँचने पर -1
, i
अपने आप को ओवरराइट करता है 0
और इस तरह लूप की स्थिति फिर से पूरी हो जाती है ...
यह मूल संस्करण था जिसे मैं अब पुन: पेश नहीं कर सकता:
यही बात i
0 से ऊपर जाने और एक के बाद एक होने के साथ काम करती है । नवीनतम जीसीसी हमेशा मेमोरी में i
पहले स्टोर arr
करता है; यह पुराने संस्करणों में भिन्न रहा होगा (शायद घोषणा के आदेश के आधार पर)। यह एक वास्तविक त्रुटि थी जिसे मैंने अपने पहले खिलौना कार्यक्रमों में उत्पादित किया था जो सरणियों से निपटता था।
इसके अलावा, यह स्पष्ट है कि अगर आप जानते हैं कि पॉइंटर्स C में कैसे काम करते हैं, लेकिन अगर आप नहीं करते हैं तो आश्चर्य हो सकता है:
आप सोच सकते हैं कि असाइनमेंट (--i)[arr]
एक त्रुटि फेंकता है, लेकिन यह मान्य और इसके बराबर है arr[--i]
। एक अभिव्यक्ति a[x]
सिंटैक्टिक शुगर है *(a + x)
जिसके लिए सूचक को अनुक्रमित तत्व के लिए गणना और डीरेफेरेंस करता है; इसके अलावा पाठ्यक्रम के अनुकूल है और इस तरह के बराबर है *(x + a)
।