2016-06-05 11 views
14

यदि कोई सी कंपाइलर फ़ील्ड को अपने मूल संरेखण में संरेखित करने के लिए एक संरचना को पैड करता है, और तब उस संरचना को प्रारंभ किया जाता है, तो क्या पैडिंग शून्य पर शुरू होती है?क्या सी संरचना पैडिंग को शून्य में प्रारंभ करता है?

उदाहरण के लिए

निम्नलिखित संरचना:

typedef struct foo_t_ { 
    int a; 
    char b; 
    int c; 
    char d; 
} foo_t; 

कई सिस्टम पर इस (खराब तरीके से तैयार) संरचना 16 के एक sizeof(foo_t) होगा, वर्ण से प्रत्येक के बाद गद्दी के 6 बाइट्स, 3 बाइट्स की कुल के साथ।

अगर हम जैसी संरचना को प्रारंभ:

foo_t foo = { .a = 1, .b = '2' }; 

तो खेतों foo.a 1 और foo.b पर सेट हो जाएगा चरित्र पर निर्धारित किया जाएगा '2'। अनिर्दिष्ट फ़ील्ड (`foo.c 'और' foo.d ') स्वचालित रूप से 0 पर सेट हो जाएंगे। सवाल यह है कि, पैडिंग के 6 बाइट्स का क्या होता है? क्या यह स्वचालित रूप से 0 पर भी सेट हो जाएगा? या यह अनिर्धारित व्यवहार है?

उपयोग के मामले है कि मैं डेटा संरचनाओं की हैश की गणना हो जाएगा:

foo_t foo = { .a = 1, .b = '2' }; 
foo_t bar = { .a = 1, .b = '2' }; 
uint32_t hash_foo = calc_hash(&foo, sizeof(foo)); 
uint32_t hash_bar = calc_hash(&bar, sizeof(bar)); 

और मुझे यकीन है कि hash_foo और hash_bar ही कर रहे हैं होना चाहता हूँ। मैं पहले संरचनाओं को साफ़ करने के लिए memset() का उपयोग करके इसकी गारंटी दे सकता हूं, फिर उन्हें प्रारंभ कर सकता हूं, लेकिन इसके बजाय सी प्रारंभिकरण का उपयोग करने के लिए क्लीनर लगता है।

प्रैक्टिस में, मेरे सिस्टम पर जीसीसी पैडिंग को भी साफ़ करता है, लेकिन मुझे नहीं पता कि इसकी गारंटी है या नहीं।

+3

किसी भी मामले में उस स्मृति को यूबी होने का संदर्भ नहीं दे रहा है? –

+1

हैश को पैडिंग पर निर्भरता के बिना वास्तविक संरचना सदस्यों का एक फ़ंक्शन क्यों नहीं बनाते? –

+0

आपके उदाहरण में, क्या आप ऐसे मामले का जिक्र कर रहे हैं जहां एक फ़ंक्शन में वैरिएबल को स्थानीय रूप से घोषित किया जा रहा है, या वैश्विक स्तर पर? –

उत्तर

14

सामान्य तौर पर, प्रति C11 के रूप में, किसी भी अप्रारंभीकृत वस्तु अध्याय के लिए §6.2.6.1/6,

जब एक मूल्य संरचना या संघ प्रकार का ऑब्जेक्ट में संग्रहीत है, एक सदस्य में शामिल ऑब्जेक्ट, किसी भी पैडिंग बाइट्स के अनुरूप ऑब्जेक्ट प्रस्तुति के बाइट अनिर्दिष्ट मान लेते हैं।

लेकिन, अगर आंशिक प्रारंभ किया जाता है, उस स्थिति में, के लिए सदस्यों की बाकी, intialization होता है के रूप में अगर एक वस्तु स्थिर या धागा भंडारण अवधि है कि, फिर, एक ही मानक के हवाले , अध्याय §6.7.9/21

एक ब्रेस संलग्न सूची में कम initializers से वहाँ तत्वों या सदस्यों की एक समग्र , वर्ण या उससे कम एक स्ट्रिंग में शाब्दिक ज्ञात की एक सरणी को प्रारंभ करने के लिए इस्तेमाल कर रहे हैं देखते हैं, तो सरणी में तत्वों की तुलना में आकार, रिम कुल मिलाकर स्पष्ट रूप से वही वस्तुओं के समान होता है जिनके पास स्थिर भंडारण अवधि होती है।

और स्थिर भंडारण अवधि के साथ वस्तुओं की अंतर्निहित आरंभीकरण के बारे में, अनुच्छेद 10

एक वस्तु स्थिर या धागा भंडारण अवधि है कि स्पष्ट रूप से प्रारंभ नहीं है, तो फिर:

  • यदि यह कुल है, तो इन नियमों के अनुसार प्रत्येक सदस्य को प्रारंभिक (पुनरावर्ती) शुरू किया जाता है, और किसी भी पैडिंग को शून्य बिट्स में प्रारंभ किया जाता है;

तो, आपके मामले में, शेष वस्तुओं के लिए गद्दी 0 होने की गारंटी हैं, लेकिन सदस्यों जो initializers प्राप्त हुआ है के लिए नहीं।

तो, कुल मिलाकर, आपको पर लागू 0 के प्रारंभिक पर निर्भर नहीं होना चाहिए, memset() का उपयोग करें।

कहा जा रहा है कि, किसी भी तरह से यह अनुशंसित नहीं है (आवश्यक) पैडिंग बाइट्स पर निर्भर होने के लिए, यदि कोई हो। सटीक सदस्य चर का प्रयोग करें और उन मानों के आधार पर हैश की गणना करें।

+0

'मेमसेट' केवल बाइट सेट करता है। लेकिन नहीं सभी प्रकारों के मान '0' के लिए" ऑल-बिट्स शून्य "एन्कोडिंग है। जैसे फ़्लोटिंग पॉइंट प्रकार और पॉइंटर (_null pointers_) - 'मेमसेट' ऐसे मामलों में काफी बेकार है। इसके अलावा दूसरा भाग (कृपया अनुच्छेद-संख्या जोड़ें!) सदस्यों में खुद को पैडिंग ** बिट्स ** के बारे में है, एजगेट के सदस्यों के बीच पैडिंग बाइट नहीं (यानी 'स्ट्रक्चर', सरणी के पास ऑब्जेक्ट्स के बीच कोई पैडिंग नहीं है) – Olaf

+0

@ ओलाफ सर, धन्यवाद टिप्पणी में, मैंने अध्यायों के साथ जवाब जोड़ दिया है।सरणी सदस्यों के बीच सभी शून्य एन्कोडिंग और पैडिंग के संबंध में, मैं आपसे सहमत हूं, लेकिन इस मामले में, केवल पैडिंग बिट लागू है, है ना? –

+0

मुझे लगता है कि ओपी सदस्यों के बीच पैडिंग बाइट्स के बारे में पूछता है, न कि प्रत्येक सदस्य में बिट्स। लेकिन मैं भी इस सवाल पर एक टिप्पणी छोड़ दूंगा। – Olaf

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