2014-09-13 7 views
10

मैं लिनक्स पर सी में structs के साथ काम कर रहा हूं। मैं बिट फ़ील्ड का उपयोग शुरू कर दिया और विशेषता "पैक" और मैं एक अजीब व्यवहार में आए: - कि बिल्कुल एक जैसे हैं -सी संरचनाओं में पैक किए गए बिट फ़ील्ड - जीसीसी

struct t1 
{ 
    int a:12; 
    int b:32; 
    int c:4; 
}__attribute__((packed)); 

struct t2 
{ 
    int a:12; 
    int b; 
    int c:4; 
}__attribute__((packed)); 

void main() 
{ 
    printf("%d\n",sizeof(t1)); //output - 6 
    printf("%d\n",sizeof(t2)); //output - 7 
} 

कैसे दोनों संरचनाओं आ बाइट्स के विभिन्न संख्या ले?

+1

क्योंकि 't2 :: b' एक विशिष्ट स्मृति स्थान होने की गारंटी है? डेटा दौड़ के बारे में सोचो। –

उत्तर

10
struct t1 // 6 bytes 
{ 
    int a:12; // 0:11 
    int b:32; // 12:43 
    int c:4; // 44:47 
}__attribute__((packed)); 

struct t1 // 7 bytes 
{ 
    int a:12; // 0:11 
    int b; // 16:47 
    int c:4; // 48:51 
}__attribute__((packed)); 

नियमित int b को बाइट सीमा से गठबंधन किया जाना चाहिए। तो इससे पहले पैडिंग है। यदि आप ca के ठीक आगे रखते हैं तो यह पैडिंग अब आवश्यक नहीं होगा। आपको शायद यह करना चाहिए, int b:32 जैसे गैर-बाइट-गठबंधन पूर्णांक तक पहुंच धीमा है।

16

आपकी संरचनाएं "बिल्कुल वही नहीं" हैं। आपके पहले व्यक्ति में लगातार तीन बिट फ़ील्ड हैं, दूसरे में एक बिट-फ़ील्ड, एक (गैर-फ़ील्ड) int है, और फिर दूसरा बिट-फ़ील्ड है।

यह महत्वपूर्ण है: लगातार (गैर-शून्य चौड़ाई) बिट-फ़ील्ड को एक स्मृति स्थान में विलय कर दिया जाता है, जबकि गैर-बिट-फ़ील्ड के बाद एक बिट-फ़ील्ड अलग-अलग स्मृति स्थान होते हैं।

आपकी पहली संरचना में एक ही स्मृति स्थान है, आपके दूसरे में तीन हैं। आप अपनी दूसरी संरचना में b सदस्य का पता ले सकते हैं, न कि आपके पहले में। b सदस्य तक पहुंच आपकी दूसरी संरचना में a या c तक पहुंचने के साथ दौड़ नहीं करती है, लेकिन वे आपके पहले में करते हैं।

बिट-फील्ड सदस्य के बाद एक गैर-बिट-फ़ील्ड (या शून्य-लंबाई बिट-फ़ील्ड) होने के बाद, इसे एक सेंसर में "बंद कर देता है", एक अलग/स्वतंत्र स्मृति स्थान/ऑब्जेक्ट का क्या पालन होगा। कंपाइलर आपके b सदस्य को बिट-फील्ड के अंदर "पैक" नहीं कर सकता है जैसा कि यह पहले स्ट्रक्चर में करता है।

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