2012-03-17 11 views
14

क्या यह कोड सख्त एलियासिंग का उल्लंघन करता है?सी सी के माध्यम से एक संरचना के पहले क्षेत्र तक पहुंचने से सख्त एलियासिंग का उल्लंघन होता है?

struct {int x;} a; 
*(int*)&a = 3 

अधिक संक्षेप में, क्या विभिन्न प्रकार के बीच कास्ट करना कानूनी है जब तक कि आदिम पढ़ने/लिखने के संचालन सही प्रकार के होते हैं?

+2

वी-टेबल संभावित रूप से पहले आते हैं, इसलिए यह यूबी क्षेत्र है। – ildjarn

+1

@ildjarn, vtables C – bdonlan

+4

@bdonlan में मौजूद नहीं है: इसे 'C++' भी टैग किया गया है। ; -] – ildjarn

उत्तर

24

सबसे पहले, यह सी §6.7.2.1/13 में कास्ट करने के लिए कानूनी है: एक संरचना वस्तु के भीतर

, गैर बिट क्षेत्र के सदस्यों और में इकाइयों जो थोड़ा-क्षेत्रों रहते है पते जो में क्रम में बढ़ते हैं जिन्हें वे घोषित कर रहे हैं। एक संरचना ऑब्जेक्ट के लिए एक सूचक, उपयुक्त रूपांतरित, इसके शुरुआती सदस्य को इंगित करता है (या यदि वह सदस्य बिट-फ़ील्ड है, फिर उस यूनिट में जिसमें वह रहता है), और इसके विपरीत। संरचना ऑब्जेक्ट में अज्ञात पैडिंग हो सकती है, लेकिन इसकी शुरुआत में नहीं।

अलियासिंग नियम के रूप में पढ़ता (§6.5/7):

एक वस्तु अपने संग्रहीत मूल्य एक lvalue अभिव्यक्ति में से एक निम्नलिखित प्रकार है कि द्वारा केवल ऐक्सेस किया गया होगा:

  • एक प्रकार वस्तु के प्रभावी प्रकार के साथ संगत,
  • एक प्रकार वस्तु के प्रभावी प्रकार के साथ संगत का एक योग्य संस्करण,
  • एक प्रकार है कि हस्ताक्षर किए या अहस्ताक्षरित प्रकार वस्तु के प्रभावी प्रकार के अनुरूप,
  • एक प्रकार है कि हस्ताक्षर किए या अहस्ताक्षरित प्रकार ऑब्जेक्ट का प्रभावी प्रकार का एक योग्य संस्करण के लिए इसी,
  • एक समेकित या संघ प्रकार जिसमें सदस्यों (जिसमें, संक्षेप में, उप-समूह या निहित संघ का सदस्य शामिल है), या
  • एक वर्ण प्रकार के बीच उपर्युक्त प्रकारों में से एक शामिल है।

यहाँ आप कोई एक "प्रकार वस्तु के प्रभावी प्रकार के साथ संगत" और "एक समग्र या संघ प्रकार है कि अपने सदस्यों के बीच ऊपर उल्लिखित प्रकारों में से एक में शामिल हैं", इसलिए का संकेत के माध्यम से इसे ऐक्सेस कर रहे होंगे या तो एलियासिंग के साथ समस्या। तो सी में, प्रश्न में सदस्य के प्रकार के लिए सूचक को सूचक कास्टिंग करके संरचना के पहले सदस्य तक पहुंचने के लिए वास्तव में पूरी तरह कानूनी है।

सी ++ में, हालांकि, आपको अक्सर C++ ऑब्जेक्ट की शुरुआत में vtables और अन्य चीजें मिलती हैं। आपके विशिष्ट मामले में, हालांकि, आपकी संरचना मानक लेआउट का है, और इसलिए यह स्पष्ट रूप से अनुमति है (§9.2/20 n3290 में, धन्यवाद ल्यूक डैंटन! - सी ++ 03 स्पष्ट रूप से एक समान नियम है, जो पीओडी ऑब्जेक्ट्स के संदर्भ में व्यक्त किया गया है) ।

+0

सी ++ निश्चित रूप से एक vtable की उपस्थिति पर कागज नहीं होगा, लेकिन मैं केवल इस तरह की अजीबता के मामलों में इसे लागू कर रहा हूं। –

+0

@ गेफ्री: "* ऐसे अजीबता वाले मामलों * *। उर्फ trivially कॉपी करने योग्य प्रकार? उर्फ कुछ ऐसा जो आपने अपने प्रश्न में उल्लेख किया होगा? – ildjarn

+1

ठीक है, सवाल का उल्लेख है कि संरचना में एक एकल int फ़ील्ड है, जिसमें अन्य चीजों के अलावा कोई vtable नहीं है। शीर्षक पहले से ही वर्बोज़ है। –

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