2012-02-05 8 views
13

संकलन समय पर endianess जाँच करने के लिए एक तरह से मैं निम्नलिखित समाधान के साथ आए हैं के लिए कुछ खोज के बाद:संकलन समय पर अंतहीनता का परीक्षण: क्या यह कॉन्स्टेक्सर मानक मानक के अनुसार सही है?

int b[is_big_endian() ? 12 : 25]; //works 
std::array<int, testendian() ? 12 : 25> c; //fails 
:

static const int a{1}; 

constexpr bool is_big_endian() 
{ 
    return *((char*)&(a)) == 1; 
} 

जीसीसी केवल कुछ संदर्भों जहां constexpr की आवश्यकता है में इस कोड को स्वीकार करता है

दूसरे मामले के लिए, जीसीसी कहते हैं error: accessing value of ‘a’ through a ‘char’ glvalue in a constant expression। मुझे मानक में कुछ भी नहीं मिला जो ऐसी चीज को रोकता है। हो सकता है कि कोई व्यक्ति स्पष्टीकरण दे सके कि किस मामले में जीसीसी सही है?

+2

चेतावनी के साथ पहले व्यक्ति को संकलित करने का प्रयास करें (संकेत: यह एक वीएलए है)। –

+0

खैर, सी ++ 11 में जहां तक ​​मुझे याद है वैरिएबल लम्बाई सरणी नहीं है। हालांकि, यह एक अलग बग है, क्योंकि मुझे -वॉल के साथ कोई चेतावनी नहीं मिलती है। बीटीडब्लू, मैं जीसीसी -4.7 – p12

+3

का उपयोग करता हूं, मुझे किसी भी तरह से संदेह है कि यह एक मौलिक स्तर पर संभव है: एंडियननेस * कार्यान्वयन * की एक संपत्ति है, लेकिन * भाषा * के नियमों को लागू करने के परिणामस्वरूप संकलन-समय जादू पूरी तरह से होता है। विशेष रूप से, किसी ऑब्जेक्ट का पता लेना संकलन-समय अवधारणा प्रतीत नहीं होता है। –

उत्तर

10

यह मैं क्या बजना 3.1 टीओटी से मिलता है:

error: constexpr function never produces a constant expression

§5.19 [expr.const]

p1 Certain contexts require expressions that satisfy additional requirements as detailed in this sub-clause; other contexts have different semantics depending on whether or not an expression satisfies these requirements. Expressions that satisfy these requirements are called constant expressions.

p2 A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression:

  • [...]
  • a reinterpret_cast (5.2.10);

तो, (char*)&(a), एक reinterpret_cast का मूल्यांकन के रूप में इस तरह के समारोह के लिए एक वैध constexpr समारोह नहीं है।

+0

आपने इसे कहाँ देखा? –

+0

@ मैथ्यू: मैंने कहां देखा? उद्धरण? यह सी ++ 11 मानक से है। – Xeo

+0

बेशक, धन्यवाद! –

2

आप Boost.Detail.Endian

यह उनकी endianness करने के लिए कई आर्किटेक्चर के एक मानचित्रण है (मैक्रो BOOST_BIG_ENDIAN, BOOST_LITTLE_ENDIAN के माध्यम से, और BOOST_PDP_ENDIAN) पर गौर करना चाहिए। जहां तक ​​मुझे पता है, इस तरह की सूची के अलावा, संकलन समय पर अंत्येष्टि निर्धारित करने का कोई वास्तविक तरीका नहीं है।

एक उदाहरण दिया गया Boost.Detail.Endian का उपयोग करता है, आप देख सकते पुस्तकालय मैं आशा करती हूं बूस्ट करने के लिए प्रस्तुत करने के लिए की समीक्षा होने के लिए: https://bitbucket.org/davidstone/endian/ (प्रासंगिक फ़ाइल byte_order.hpp है, लेकिन unsigned.hpp रूप में अच्छी तरह अगर आप चाहते हैं के लिए आवश्यक है बस मेरे कार्यान्वयन का उपयोग करने के लिए)।

0

यदि N3620 - नेटवर्क बाइट ऑर्डर रूपांतरण लागू किया गया है, तो आप अंतहीनता की जांच के लिए constexpr ntoh का उपयोग करने में सक्षम होंगे, लेकिन याद रखें कि मध्यम-एंडियन जैसे दुर्लभ आर्किटेक्चर हैं और आप कभी भी सभी का समर्थन नहीं कर पाएंगे उन्हें।

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