2010-04-26 15 views
7

नीचे सी ++ कोड टुकड़ा के लिए:अनिश्चित आकार, खाली ब्रैकेट के साथ परिभाषित स्थैतिक सरणी?

class Foo { 
    int a[]; // no error 
}; 

int a[];  // error: storage size of 'a' isn't known 

void bar() { 
    int a[]; // error: storage size of 'a' isn't known 
} 

क्यों सदस्य चर एक त्रुटि भी कारण नहीं है? और इस सदस्य चर का अर्थ क्या है?

मैं कोडब्लॉक 8.02 के माध्यम से जीसीसी संस्करण 3.4.5 (mingw-Vista विशेष) का उपयोग कर रहा हूं।

class Foo { 
    int a[]; // warning C4200: nonstandard extension used : zero-sized array in struct/union - Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array 
}; 

int a[]; 

void bar() { 
    int a[]; // error C2133: 'a' : unknown size 
} 

अब, यह भी कुछ explaination की जरूरत है: -

विजुअल स्टूडियो एक्सप्रेस 2008 को Microsoft (R) C/C++ अनुकूलन संकलक 15.00.30729.01 80x86 के लिए, मैं निम्नलिखित संदेश मिला है।

+0

कैप्शन में "स्थैतिक सरणी" का उल्लेख है। आपके प्रश्न में ये "स्थैतिक सरणी" कहां हैं? मुझे किसी भी "स्थैतिक सरणी" के लिए एक संदर्भ नहीं दिख रहा है। – AnT

+0

मेरा मतलब स्थिर रूप से आवंटित सरणी है। यदि आवश्यक हो तो कृपया प्रश्न को संपादित करने के लिए स्वतंत्र महसूस करें। धन्यवाद। –

उत्तर

6

सी 99 एक 'लचीला' सरणी सदस्य नामक किसी चीज़ का समर्थन करता है जिसे संरचना के अंतिम सदस्य होने की अनुमति है। जब आप गतिशील रूप से ऐसी संरचना आवंटित करते हैं तो आप सरणी के लिए स्मृति प्रदान करने के लिए malloc() से अनुरोध की गई राशि को बढ़ा सकते हैं।

कुछ कंपाइलर इसे C90 और/या C++ के विस्तार के रूप में जोड़ते हैं।

तो आप की तरह कोड हो सकता है निम्नलिखित:

struct foo_t { 
    int x; 
    char buf[]; 
}; 


void use_foo(size_t bufSize) 
{ 
    struct foo_t* p = malloc(sizeof(struct foo_t) + bufSize); 

    int i; 

    for (i = 0; i < bufSize; ++i) { 
     p->buf[i] = i; 
    } 
} 

आप सीधे एक लचीला सरणी के सदस्य के साथ एक struct को परिभाषित नहीं कर सकते हैं संकलक के रूप में (एक स्थानीय या एक वैश्विक/स्थिर चर के रूप में) नहीं होगा पता है कि इसके लिए कितनी मेमोरी आवंटित की जाएगी।

मैं ईमानदारी से यकीन है कि कैसे आप आसानी से सी ++ के new ऑपरेटर के साथ ऐसी बात का उपयोग करेंगे नहीं कर रहा हूँ - मुझे लगता है कि आप malloc() और उपयोग नियुक्ति new का उपयोग कर वस्तु के लिए स्मृति को आबंटित करना होगा। शायद operator new के कुछ वर्ग/संरचना विशिष्ट अधिभार का उपयोग किया जा सकता है ...

2
class Foo { 
    int a[]; // OK in C, invalid in C++. Does not work with inheritance. 
}; // Idea is that structure is "extended" indefinitely by an array. 
    // May work on your compiler as an extra feature. 

int a[];  // error in C and C++: storage size of 'a' isn't known 

void bar() { 
    int a[]; // error in C and C++: storage size of 'a' isn't known 
} 

extern int a[]; // OK: storage size may be declared later. 

int a[5]; // declaration of size before use. 

अनिर्दिष्ट आकार वाला एक सरणी प्रकार अपूर्ण है। 8.3.4/1:

यदि निरंतर अभिव्यक्ति छोड़ी जाती है, तो डी के पहचानकर्ता का प्रकार "अज्ञात बाध्यता की टी व्युत्पन्न-प्रकार-सूची-सारणी सरणी" है, एक अपूर्ण वस्तु प्रकार।

यह आदेश, एक परिभाषा में भाग लेने के a की परिभाषा यानी एक आकार विनिर्देश या निर्दिष्ट आकार की एक सरणी के साथ प्रारंभ शामिल होना चाहिए में पूरा किया जाना चाहिए।

+1

मुझे समझ में नहीं आता है कि "उपयोग से पहले पूरा होना चाहिए" टिप्पणी। सी ++ में अनिर्दिष्ट आकार की एक सरणी * उपयोग * के लिए यह पूरी तरह से कानूनी है। आप इसे 'आकार' लागू नहीं कर सकते हैं, लेकिन आप कानूनी रूप से अपने तत्वों तक पहुंच सकते हैं। – AnT

+0

@Andrey: अनिर्दिष्ट आकार की सरणी के रूप में घोषित एक फ़ंक्शन तर्क में 'T *' टाइप किया गया है। यह एक और प्रकार के लिए एक क्षय है। क्या कोई और उदाहरण है जिसके बारे में मुझे अवगत होना चाहिए? आपका उत्तर किसी को दिखाना प्रतीत नहीं होता है। – Potatoswatter

+0

मैं फ़ंक्शन तर्कों के बारे में बात नहीं कर रहा था, जो एक पूरी तरह से अलग कहानी है। मैं आपके उदाहरण में 'बाहरी int []' घोषणा के लिए रेफर कर रहा था। एक बार जब आप उस तरह की सरणी घोषित कर लेते हैं, तो आप इसे * पहले से ही * उपयोग कर सकते हैं। मैं देखता हूं कि आपने "उपयोग" के संदर्भ को हटा दिया है। – AnT

0

हमने इसका उपयोग किसी प्रकार के परिवर्तनीय लंबाई रिकॉर्ड को दर्शाने के लिए किया है। कुछ हेडर फ़ाइल की तरह कुछ है जिसमें डेटा के बाद कितनी संरचनाएं चलनी हैं, इस बारे में जानकारी है। यह एक चर लंबाई लंबाई है और मैंने पाया है कि यह compilers के बीच अच्छी तरह से समर्थित नहीं है। कुछ सरणी चाहते हैं []; और कुछ सरणी चाहते हैं [0]; (पुराना तरीका)।

11

C++ भाषा केवल गैर परिभाषित करने घोषणाओं में सरणी आकार को छोड़ते हुए अनुमति देता है

extern int a[]; // non-defining declaration - OK in C++ 

int a[]; // definition - ERROR in C++ 

int a[5]; // definition - OK, size specified explicitly 
int a[] = { 1, 2, 3 }; // definition - OK, size specified implicitly 

गैर स्थिर वर्ग के सदस्य decarations हमेशा सरणी आकार

struct S { 
    int a[]; // ERROR in C++ 
}; 

जबकि स्थिर वर्ग के सदस्य निर्दिष्ट करने के लिए आवश्यक हैं decarations आकार

को छोड़ सकता है 0

(उसी सदस्य के परिभाषा, निश्चित रूप से, आकार निर्दिष्ट करना होगा)।

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