2015-10-30 5 views
9

विशेष रूप से जीसीसी पर (यानी, दोनों जीसीसी के साथ संकलित) पर, निम्नलिखित दो कामों के बीच अंतर क्या हैं?जीआरसीसी पर #pragma पैक (पुश, एन)/# प्राग्मा पैक (पॉप) और __attribute __ ((__ packed__, aligned (n)) के बीच अंतर क्या हैं?

struct foo1 { 
    char a; 
    int b; 
} __attribute__((__packed__, aligned(n))); 

और:

#pragma pack(push, n) 
struct foo2 { 
    char a; 
    int b; 
}; 
#pragma pack(pop) 

वे appear to behave differently:

foo1 f1; 
foo2 f2; 

int& i1 = f1.b; // ok 
int& i2 = f2.b; // cannot bind packed field 'f2.foo2::b' to 'int&' 

क्यों वहाँ एक में कोई त्रुटि अभी तक अन्य नहीं है? क्या मेमोरी लेआउट कम से कम हैं?

उत्तर

3

आप यह नहीं कहते कि आप किस जीसीसी का उपयोग कर रहे हैं, लेकिन आप उपयुक्त मैनुअल on-line पा सकते हैं। वे सभी इन संबंधों में काफी संगत हैं, हालांकि, एक बार परिभाषित गुणों और प्रागों के व्यवहार के रूप में, आमतौर पर संगतता के लिए संस्करणों में बनाए रखा जाता है। मैं जीसीसी 4.9.3 के लिए मैन्युअल से विशिष्ट उद्धरण तैयार करूंगा, वर्तमान में जीसीसी 4 श्रृंखला से नवीनतम उपलब्ध संस्करण। विशेष रूप से, type attributes पर और structure-packing pragmas पर अनुभाग प्रासंगिक हैं।

#pragma निर्देशों कि सदस्यों संरचनाओं, यूनियनों, और वर्गों (शून्य चौड़ाई बिट क्षेत्रों के अलावा अन्य) के की अधिकतम संरेखण बदलने:

जीसीसी मैनुअल #pragma pack और दोस्तों के बारे में कहते हैं बाद में परिभाषित किया गया।

(जोर जोड़ा गया)। यह __attribute__((packed)) का कहना है:

यह लक्षण struct या संघ प्रकार परिभाषा से जुड़ी, यह बताता है कि प्रत्येक सदस्य संरचना या संघ के (शून्य चौड़ाई बिट क्षेत्रों के अलावा अन्य) स्मृति की आवश्यकता को कम करने के रखा गया है।

यह __attribute__ ((aligned(n))) का कहना है:

यह विशेषता निर्दिष्ट निर्दिष्ट प्रकार, बाइट में मापा की चर के लिए एक न्यूनतम संरेखण।

(जोर जोड़ा गया)।

इस प्रकार, #pragma pack(n), push के साथ या बिना, सामान्य रूप से, संरचना प्रकार के लिए __attribute__((packed, aligned(n)) को जोड़ने जैसा ही नहीं है। पूर्व निर्दिष्ट करता है कि प्रभावित संरचनाओं के सदस्यों को n -बाइट या बेहतर सीमाओं पर गठबंधन किया जाना चाहिए। उत्तरार्द्ध निर्दिष्ट करता है कि प्रभावित संरचना के सदस्यों को न्यूनतम अनुमत पैडिंग के साथ पैक किया जाना चाहिए, और समग्र संरचना के उदाहरणों के लिए चुनी गई संरेखण आवश्यकता n से कम नहीं होनी चाहिए। न केवल वे वही हैं, वे भी समान नहीं हैं।

आपको यह पता होना चाहिए कि #pragma pack(1) संरचना परिभाषा को प्रभावित करने वाले उदाहरणों के लेआउट पर समान प्रभाव डालता है क्योंकि __attribute__((packed)) उस संरचना की परिभाषा को जोड़ता है।भले ही वे एक ही अंत को पूरा करते हैं, फिर भी, वे एक ही चीज़ नहीं हैं। दोनों के व्यवहार और प्रभाव सी ++ विनिर्देश के बाहर हैं, और जीसीसी पूरी तरह से अन्य तरीकों से उनका इलाज करने के अपने अधिकारों के भीतर है।

यदि आप संरचना सदस्यों के संरेखण को प्रभावित करने के लिए विशेषताओं का उपयोग करना चाहते हैं, तो आपको सदस्य-दर-सदस्य आधार पर कम से कम कुछ विशेषताओं को लागू करने की आवश्यकता होगी। उदाहरण के लिए ...

struct foo1 { 
    char a; 
    int b __attribute__((aligned(n))); 
} __attribute__((packed)); 

... के रूप में एक ही प्रभाव ...

#pragma pack(push, n) 
struct foo2 { 
    char a; 
    int b; 
}; 
#pragma pack(pop) 

..., पर n आधार हो सकता है।

+0

* "आपको यह पता होना चाहिए कि #pragma पैक (1) का एक संरचना परिभाषा पर समान प्रभाव है जैसा कि __attribute __ ((पैक)) को परिभाषित करता है" *: हालांकि, एक संकलित करता है, दूसरा उदाहरण में नहीं है ओपी द्वारा पोस्ट किया गया। –

+0

@ m.s। वे दोनों मेरे लिए g ++ 4.4.7 के साथ ठीक संकलित करते हैं। फिर फिर, उसका मूल उदाहरण भी है। मैंने फिर भी उस क्षेत्र में थोड़ा सा संकीर्ण और तेज करने के लिए अपने जवाब को संशोधित किया है। –

+0

वास्तव में, [g ++ 4.4.7 (और कुछ और पुराने संस्करण) इस कोड को संकलित करते हैं] (http://melpon.org/wandbox/permlink/evDwNE8RgMwxO9HB), जबकि [g ++ 4.7.3 (और बाद में) नहीं है] (http://melpon.org/wandbox/permlink/zQZWjWa4T2CbLkgD) –

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