2008-11-11 11 views
28

मैं कुछ कम स्तर सीरियलाइज़ेष्ण कोड कि टेम्प्लेटेड है, और मैं स्पष्ट रूप से compiletime पर सिस्टम के endianness पता करने के लिए (क्योंकि टेम्पलेट्स सिस्टम के endianness के आधार पर माहिर हैं) की जरूरत है।मशीन की अंतहीनता निर्धारित करने के लिए सी ++ शैली संकलन-समय दावा करने का कोई तरीका है?

अभी मेरे पास कुछ प्लेटफ़ॉर्म परिभाषित करने वाला एक शीर्षलेख है, लेकिन मुझे कुछ टेम्पलेट परीक्षण (जैसे static_assert या boost_if) के साथ अंतहीनता के बारे में दावा करने के लिए कुछ करना होगा। मेरे कोड होने के कारण संकलित करने की आवश्यकता होगी और मशीनों की एक विस्तृत श्रृंखला, कई विशिष्ट विक्रेताओं, और शायद उन डिवाइसों पर चलने की आवश्यकता होगी जो 2008 में मौजूद नहीं हैं, इसलिए मैं वास्तव में अनुमान नहीं लगा सकता कि उस शीर्षलेख वर्षों में क्या हो सकता है सड़क के नीचे। और चूंकि कोड-बेस के पास लगभग 10 वर्षों का अपेक्षित जीवनकाल है। तो मैं हमेशा के लिए कोड का पालन नहीं कर सकता।

उम्मीद है कि यह मेरी स्थिति स्पष्ट करता है।

तो किसी को भी, एक संकलन समय परीक्षण है कि endianness निर्धारित कर सकते हैं के बारे में पता करता विक्रेता विशिष्ट परिभाषित करता है पर निर्भर रहे बिना?

उत्तर

18

आप autoconf का उपयोग कर रहे हैं, तो आप (स्थापित करने WORDS_BIGENDIAN डिफ़ॉल्ट रूप से परिभाषित)

बारी-बारी से काम करने के लिए उपयोग कर सकते हैं AC_C_BIGENDIAN मैक्रो, जो काफी गारंटी है, आप की तरह कुछ की कोशिश कर सकते निम्नलिखित (autoconf से लिया गया) एक परीक्षण है कि शायद दूर अनुकूलित किया जाएगा प्राप्त करने के लिए

int is_big_endian() 
{ 
    union { 
     long int l; 
     char c[sizeof (long int)]; 
    } u; 

    u.l = 1; 

    if (u.c[sizeof(long int)-1] == 1) 
    { 
     return 1; 
    } 
    else 
     return 0; 
} 
+2

धन्यवाद, यह एक अच्छी चाल है। और मुझे लगता है कि मैं इसे थोड़ा पुनर्वितरण के साथ लागू कर सकता हूं। अभी तक सुनिश्चित नहीं है, लेकिन यह एक अच्छा नेतृत्व है। –

5

हम्म, यह एक दिलचस्प सवाल है। मेरी शर्त यह है कि यह संभव नहीं है। मुझे लगता है कि आपको मैक्रोज़ का उपयोग जारी रखना होगा, और BOOST_STATIC_ASSERT(!BIG_ENDIAN);, या static_assert सी ++ 0x में जाना होगा। कारण मुझे लगता है कि ऐसा इसलिए है क्योंकि एंड्रॉन्स एक संपत्ति है यदि आपका निष्पादन वातावरण। हालांकि, स्थिर समय पर static_assert माना जाता है।

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

+0

हाँ मैं अपने आप को यह पता लगाने में सक्षम नहीं किया गया है (जीसीसी, कम से कम, अन्य शाखा को हटाता है), और जैसा कि आप कहते हैं कि यह भी संभव नहीं हो सकता । लेकिन मैंने अन्य परिस्थितियों के लिए पहले असंभव देखा है ... तो शायद, शायद कोई यहां एक महान विचार के साथ आ सकता है :) –

+0

यह काम क्यों नहीं कर सकता: '# परिभाषित करें IS_LITTLE_ENDIAN char (0x00ff)'। यह समाधान @ माइकलबुर के जवाब से थोड़ा प्रेरित है। यह टेम्पलेट्स के साथ अच्छी तरह से काम करता है, [डेमो] (http://ideone.com/JAS7mO)। सटीक होने के लिए 'char' के स्थान पर 'uint8_t' मानें। – iammilind

+1

@iamm मुझे नहीं लगता कि सी या सी ++ में बिटपटरर्न बनाना संभव है। आप मूल्य 255 का निर्माण कर रहे हैं और फिर इसे चार में डाल दें। भले ही सी ने आपको थोड़ा सा प्रतिनिधित्व निर्दिष्ट करने की इजाजत दी हो, फिर भी आप उस बिटपटर को स्मृति की सामग्री के रूप में समझने के लिए कंपाइलर को मनाने के लिए तैयार हैं और इसे तत्काल मान के बजाय इसे एक रजिस्टर में लोड करते हैं। पंजीकरण-अनन्य जैसे कि छंटनी और शून्य विस्तार के लिए, अंतहीनता अप्रासंगिक आईआईआरसी है। –

18

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

+0

शीर्षलेख के लिंक के लिए धन्यवाद। यह एक अच्छा संदर्भ है। और मेरे पास जो भी है। –

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

  • कोई संबंधित समस्या नहीं^_^