2015-03-30 5 views
6

structs के लिए जहां समानता का अर्थ है प्रत्येक डेटा सदस्य के समान रूप से व्युत्पन्न प्रकार और बाइट समानता, जब कभी भी, संरचना सुरक्षित रूप से बाइट्स की सरणी के रूप में धोया जा सकता है?एक संरचना को बाइट्स की सरणी के रूप में सुरक्षित रूप से कब रखा जा सकता है?

इस दस्तावेज़

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3333.html

शीर्षक "बाइट एरेस वस्तुओं Hashing" के तहत पता चलता है कि किसी भी गद्दी के साथ structs सुरक्षित रूप से बाइट्स की एक सरणी के रूप में टुकड़ों में बांटा नहीं जा सकता है।

बाइट्स की सरणी के रूप में सुरक्षित रूप से हैश को संरक्षित करने के लिए आवश्यक पैडिंग के लिए एक स्पष्ट परीक्षण है? क्या यह पर्याप्त है?

यदि ऐसा है, तो क्या निम्न स्केच उचित रूप से उस परीक्षण को चित्रित करता है?

#include <cstddef> 
#include <iostream> 

struct A 
{ 
    int i; 
    float f; 
    char c; 
}; 
// hashing would start at offs_i (possibly hopping over a v-table) and end at 
// offs_c + sizeof(char) 

int main() 
{ 
    const std::size_t size_A = sizeof(A); 
    const std::size_t size_int = sizeof(int); 
    const std::size_t size_float = sizeof(float); 
    const std::size_t size_char = sizeof(char); 
    const std::size_t offs_i = offsetof(A, i); 
    const std::size_t offs_f = offsetof(A, f); 
    const std::size_t offs_c = offsetof(A, c); 

    bool padded = false; 
    if (offs_f != size_int) 
     padded = true; 
    else if (offs_c != size_int + size_float) 
     padded = true; 

    std::cout << "padded? " << std::boolalpha << padded << std::endl; 
} 

एक struct गद्दी हैं, तो क्या वहाँ बाइट्स की एक सरणी है, उदा hashing अनुमति देने के लिए वैकल्पिक हल के लिए किसी भी तरह है पैडिंग बिट्स को शून्य-आउट करना?

"सुरक्षित" यहां दो स्ट्रक्चर का अर्थ है जो बराबर इच्छा हैश की समान मानों की तुलना करें।

+0

क्या आपको अर्थपूर्ण, सदस्य-वार हैशिंग करने से रोक रहा है हर किसी की तरह? –

+0

@LightnessRacesinOrbit आप एक ऐसा फ़ंक्शन कैसे बना सकते हैं जिसमें एक सामान्य संरचना प्रकार है? – Shoe

+0

आप नहीं करेंगे, क्योंकि यह समझ में नहीं आता है। – Puppy

उत्तर

4

बहुत ज्यादा कभी नहीं। मानक परिभाषित नहीं करता है कि विरासत कैसे कार्यान्वित किया जाता है, उदा। vtable पॉइंटर्स के साथ, इसलिए इस बात की कोई गारंटी नहीं है कि दो वर्ग जो बराबर अधिक व्युत्पन्न प्रकार के हैं, में कोई कार्यान्वयन-विशिष्ट विरासत-संबंधित डेटा बराबर होगा।

इसके अलावा, चूंकि वे पीओडी नहीं हैं, ऑफसेटफ को काम करने या सार्थक परिणामों का उत्पादन करने की गारंटी नहीं है- मेरा मानना ​​है कि यह वास्तव में केवल सादा यूबी है।

लंबी और छोटी है, बाइट्स के बाइट के रूप में संरचनाओं का इलाज करने की कोशिश करने से परेशान न हों क्योंकि वे नहीं हैं।

पेपर पर अपने इरादों के संबंध में, यह संभवतः कुछ रबीद "एर माह गेर्ड प्रदर्शनों" के लिए रियायत की संभावना है! एक वास्तविक चीज़ के बजाय समिति पर कुत्ते जो वह करना चाहता है।

is_trivially_copyable<T>::value && 
is_standard_layout<T>::value && 
is_contiguous_layout<T>::value 

struct ही है और सभी सदस्यों के लिए रिकर्सिवली सच करने के लिए है कौन सा:

+0

मैं कहूंगा कि कम से कम पीओडी structs बाइट्स के सरणी के रूप में हैश के लिए काफी आम है, यह कुशल और प्राकृतिक है। यह सुनिश्चित करने के लिए पहले स्ट्रक्चर को शून्य से बाहर करें कि पैडिंग में यादृच्छिक मान हैश को परिवर्तित नहीं करते हैं। –

+0

बाइट्स की सरणी के रूप में यादृच्छिक रूप से किसी चीज़ का इलाज करने के बारे में कुछ भी स्वाभाविक नहीं है। न ही, वास्तव में, कुशल, क्योंकि आप ऐसी चीजें हैं जिनके पास पैडिंग की तरह कोई प्रभाव नहीं पड़ता है, और आप एक सभ्य हैश उत्पन्न करने के लिए प्रकार के ज्ञान का उपयोग नहीं कर सकते हैं। – Puppy

+0

मैं असहमत हूं। स्ट्रक्चर और हैश को चार या 32-बिट शब्दों की सरणी के रूप में बस शून्य करें। –

2

कागज आप prety ज्यादा राज्यों की आवश्यकताओं को संदर्भित किया है।

पहले दो चेक पहले से ही मानक लाइब्रेरी का हिस्सा हैं और आप is_contiguous_layout<T>::value को अपने आप से कार्यान्वित कर सकते हैं। आधार के रूप में यह संरचना के आकार के साथ अपने सदस्यों के आकार की तुलना करने के लिए पर्याप्त होना चाहिए। मुझे नहीं लगता, ऑफसेट की जांच वास्तव में आवश्यक है।

यह निश्चित रूप "सामान्य" प्लेटफार्मों (CHAR_BIT == 8, 2-पूरक) अगर आपके प्रकार केवल पूर्णांक प्रकार से बना है पर काम करना चाहिए। मुझे यकीन नहीं है कि, अगर यह बूल और फ़्लोटिंग पॉइंट नंबरों के साथ भी काम करता है, क्योंकि मेरा मानना ​​है कि मानक एक चर के मूल्य और उसके बिट प्रतिनिधित्व के बीच एक अद्वितीय दो-तरफा मानचित्रण को अनिवार्य नहीं करता है।

संपादित करें: मुझे अभी एहसास हुआ कि आप of same most derived type की स्थिति को संतुष्ट नहीं कर सकते हैं, यदि व्युत्पन्न कक्षा में कोई सदस्य नहीं जोड़ता है या यदि आप दो अलग-अलग वर्गों की तुलना करते हैं जो समान सदस्य होते हैं। तो आपको अलग-अलग प्रकार के लिए खाते रखना होगा।

+0

ऑफ़सेट कुछ ज्ञान के साथ जरूरी नहीं है लेकिन मुझे लगता है कि 'is_contiguous_layout :: value' के योग कार्यान्वयन के बारे में iffy भी है। – Praxeolitic

+0

@Praxeolitic: अगर 'size_A == size_int + size_float + size_char' मुझे नहीं लगता कि सदस्यों के बीच कोई पैडिंग कैसे हो सकती है। फिलिप रोज़ेन द्वारा उल्लिखित - रेफ, समस्या मौलिक प्रकार हैं (मैंने उस हिस्से को मेरे उत्तर में जोड़ा)। – MikeMB

0

यदि संरचना पीओडी है, तो आपको प्रारंभिक संरचना में पूरी संरचना के लिए केवल 0 में bzero या memcpy करने में सक्षम होना चाहिए, फिर बाइट्स की सरणी के रूप में हैशिंग ठीक और कुशल होना चाहिए।

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

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