2010-09-23 21 views
15

जब आप ऋणात्मक लंबाई की सरणी बनाते हैं तो सी में क्या होता है?नकारात्मक लंबाई की एक सरणी घोषित करना

उदाहरण के लिए:

int n = -35; 

int testArray[n]; 

for(int i = 0; i < 10; i++) 
    testArray[i]=i+1; 

इस कोड को संकलित कर देगा (और -Wall के साथ कोई चेतावनी सक्षम लाता है), और यह आप बिना किसी समस्या के testArray[0] को असाइन कर सकते लगता है। अतीत को असाइन करना जो या तो एक सेगफॉल्ट या अवैध निर्देश त्रुटि देता है, और सरणी से कुछ भी पढ़ने से कहते हैं, "अपरिपक्व जाल" (मैं उस से परिचित नहीं हूं)। मुझे एहसास है कि यह कुछ हद तक अकादमिक है, और (उम्मीद है) वास्तविक जीवन में कभी नहीं आएगा, लेकिन क्या कोई विशेष तरीका है कि सी मानक ऐसे सरणी का इलाज करने के लिए कहता है, या क्या यह कंपाइलर से कंपाइलर में भिन्न होता है?

+0

'स्टेटमेंट' के अंत में एक अनजान अर्धविराम (';') है, मुझे लगता है ... – Arun

+0

धन्यवाद, मैंने इसे ठीक किया! – jonmorgan

उत्तर

20

यह अपरिभाषित व्यवहार है क्योंकि यह एक "करेगा" बाधा टूट जाता है:

C99 §6.7.5.2: आकार एक अभिव्यक्ति है कि है नहीं एक पूर्णांक निरंतर अभिव्यक्ति है

हैं। .. ... प्रत्येक बार इसका मूल्यांकन किया जाता है, यह शून्य से अधिक मान होगा।

+0

धन्यवाद! यही वही है जो मैं ढूंढ रहा था। – jonmorgan

+2

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

3

अपरिभाषित व्यवहार, मुझे विश्वास है, हालांकि मुझे उस पर उद्धरण न दें।

यह त्रुटि error: size of array 'testArray' is negative देता जीसीसी में:

int testArray[-35]; 

हालांकि, आप के रूप में देखा है:

int n = -35; 
int testArray[n]; 

दोनों -Wall और डब्ल्यू के साथ भी एक त्रुटि नहीं देता है।

हालांकि, यदि आप -पैंथिक ध्वज का उपयोग करते हैं, तो जीसीसी चेतावनी देगा कि आईएसओ सी 9 0 परिवर्तनीय लंबाई सरणी को रोकता है।

+0

वास्तव में यह क्या करता है? मुझे लगता है कि यह इसे बिना हस्ताक्षरित के रूप में व्याख्या करता है ताकि आपको (MAX_INT-35) –

+1

@ मार्टिन बेकेट: चूंकि यह अपरिभाषित व्यवहार है, इसलिए कंपाइलर कुछ भी करने के लिए स्वतंत्र हैं, भले ही वे अनुचित व्यवहार हैं, क्योंकि ऋणात्मक लंबाई सरणी आवंटित करना एक है संकलित बकवास। अगर मुझे सी को फिर से डिजाइन करने की अनुमति दी गई थी, तो मैं सरणी की लंबाई घोषणा और एक 'हस्ताक्षरित int' को अनुक्रमणित कर दूंगा, और संकलक को टाइप त्रुटि को उत्सर्जित करने की आवश्यकता होगी जब 'हस्ताक्षर int' लंबाई या अनुक्रमण संचालन के लिए उपयोग किया जाता है। –

+0

प्रश्न को C99 टैग किया गया था, इसलिए परिवर्तनीय लंबाई सरणी का पहलू मानकों के दृष्टिकोण से ठीक है। –

0

compilation के लिए विजुअल स्टूडियो एरो संदेश, आप एक खाली सरणी कहने के लिए -1 का उपयोग कर सकते हैं। यह int की अपेक्षा करता है और आप int गुजर रहे हैं, इसलिए कोई कंपाइलर त्रुटि नहीं है।

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