2011-10-11 17 views
7

मैंने पढ़ा है कि अगर आप इस तरह दो structs की घोषणा:क्या यह कोड सी मानक द्वारा गारंटी है?

struct Node { 
    int a, b, c; 
}; 

struct DerivedNode { 
    struct Node base; 
    int d, e, f; 
}; 

तो फिर तुम संकेत उन्हें इस तरह का उपयोग कर सकते हैं:

struct DerivedNode myDerivedNode; 
struct Node *regularNode = (struct Node *) &myDerivedNode; 

regularNode->a = 3; 

दूसरे शब्दों में, a, b, c के लिए पता ऑफसेट ही कर रहे हैं struct Node और struct DerivedNode के भीतर। तो आप इसके बारे में एक तरह का बहुरूपता प्राप्त कर सकते हैं, जहां आप जबरन (struct Node *)-डेरिवडेड पॉइंटर को पास कर सकते हैं जहां भी नोड पॉइंटर सामान्य रूप से लिया जाएगा।

मेरा सवाल यह है कि क्या इस व्यवहार की गारंटी है। मुझे पता है कि कुछ अजीब स्मृति संरेखण के मुद्दे हैं और संकलक कभी-कभी मेमोरी में बेहतर पैकिंग प्राप्त करने के लिए फ़ील्ड को पीछे छोड़ देता है। क्या base फ़ील्ड कहीं भी स्थित होगा लेकिन struct DerivedNode की शुरुआत होगी?

+0

आप कई स्थानों पर 'struct' कीवर्ड भूल गए हैं, नहीं? –

+0

@ जेन्स ओह हाँ शायद। क्षमा करें –

उत्तर

13

यह मानक द्वारा काम करने की गारंटी है।

एक संरचना एक प्रकार का एक क्रम से मिलकर है: structs में सदस्यों आदेश आपके द्वारा निर्दिष्ट और पहले सदस्य हमेशा दिखाई देता है ऑफसेट एएनएसआई सी मानक से 0.

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

यह बताता है कि सदस्यों को अनुक्रमिक रूप से निर्धारित किया गया है।

संरचना वस्तु के भीतर अज्ञात पैडिंग हो सकती है, लेकिन इसकी शुरुआत में नहीं।

मतलब यह है कि पहले सदस्य पर रखा गया है ऑफसेट 0.

नोट: TC3 सितंबर 2007 मसौदा: स्टैंडर्ड अंश आईएसओ/आईईसी 9899 की धारा 6.7.2.1 से लिया।

3

जैसा कि डेविड ने कहा है कि baseDerivedNode में पहला तत्व बना हुआ है।

लेकिन आम तौर पर यह खराब अभ्यास है। मैं बहुत परिस्थितियों को समझ नहीं सकता है जहाँ आप यह नहीं कह सकते

struct Node *regularNode = &myDerivNode.base; 

जो मामले में बहुत स्पष्ट और त्रुटियों की संभावना कम आप बाद में अपने संरचनाओं को संशोधित है।

+0

+1 मैं पूरी तरह से इस से सहमत हूं। –

+0

परिस्थिति यह है कि मैं डेटा संरचना वर्ग में हूं जहां मैं 1 9 75 में एक शाखा को बाहर कर रहा हूं (इसके लिए प्रतीक्षा करें ..) बाइनरी खोज। : पी –

1

यह आपके प्रश्न का उत्तर नहीं देगा, लेकिन जो मानक एएनएसआई (आईएसओ) सी लिखने की परवाह करता है वह gcc -pedantic या -pedantic-errors के साथ अपना कोड संकलित कर सकता है। उन विकल्पों को कोड की गैर मानक लाइनों पर चेतावनियों/त्रुटियों को संकलित करना चाहिए।

ध्यान दें कि यह 100% प्रभावी नहीं है, man gcc से:

[-pedantic] कुछ गैर आईएसओ प्रथाओं पाता है, लेकिन सभी नहीं --- केवल के लिए उन जो आईएसओ सी एक की आवश्यकता है नैदानिक, और कुछ अन्य जिसके लिए निदान जोड़ा गया है।

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