2012-08-27 8 views
8

मैं निम्नलिखित कोडअंक

#include <iostream> 
#include <array> 

class testClass 
{ 
    std::array<int, 2> testArray; 

    public: 
     testClass(); 
     void func() const; 

}; 

testClass::testClass() : testArray({{1, 2}}) 
{ 
} 

void testClass::func() const 
{ 
    for (int i = 0; i < 2; ++i) 
     std::cout << testArray.at(i) << '\n' << testArray[i] << '\n';  
} 


int main() 
{ 
    testClass test; 
    test.func(); 
} 

साथ अजीब व्यवहार सीमा एक सदस्य एसटीडी जाँच :: MinGW (जीसीसी 4.7.0) के साथ सरणी हो रही है के रूप में यह केवल ऊपर फसलों जब -O साथ संकलित, मैं व्यक्तिगत झंडे -O रूप से सक्षम करने की कोशिश की, लेकिन यह किसी भी आगे को कम नहीं कर सका आउटपुट

0 
1 
0 
2 

त्रुटि अनुकूलन से संबंधित प्रतीत हो रहा है है। फ़ंक्शन गैर-कॉन्स बनाना भी समस्या को हल करता है। क्या यह एक बग हो सकता है या क्या मुझे कुछ याद आ रहा है?

* संपादित

यह संकुचित नीचे, .at()

#include <iostream> 
#include <array> 

int main() 
{ 
    std::array<int, 2> const testArray = {1, 2}; 

    for (int i = 0; i < 2; ++i) 
     std::cout << testArray.at(i) << '\n' << testArray[i] << '\n';  
} 

एक ही उत्पादन का const संस्करण में एक बग की तरह दिखता है ऊपर के रूप में -std=c++11 -O Windows XP SP3 और विंडोज 7 पर MinGW 4.7.0 उपयोग करने के साथ संकलित SP1।

* संपादित 2

एक ही उत्पादन फिर से

#include <iostream> 
#include <array> 

int main() 
{ 
    typedef std::array<int, 2> Tarray; 
    Tarray test = {1, 2}; 

    for (int i = 0; i < 2; ++i) 
     std::cout << const_cast<Tarray const*>(&test)->at(i) << '\n' << test.at(i) << '\n';  
} 
+0

http://liveworkspace.org/code/b0d5b3c7398f7e1a2e36838f23fc943c अच्छी तरह से काम करता है। – ForEveR

+4

यह निश्चित रूप से मेरे लिए एक बग की तरह दिखता है। –

+0

यह मेरे लिए [एक अलग आउटपुट] (http://ideone.com/ZhIsS) बनाता है ... – dasblinkenlight

उत्तर

5

यह सरणी हैडर

#ifdef __EXCEPTIONS 
    constexpr const_reference 
    at(size_type __n) const 
    { 
return __n < _Nm ? 
     _M_instance[__n] : throw out_of_range(__N("array::at")); 
    } 
#else 
    const_reference 
    at(size_type __n) const 
    { 
if (__n >= _Nm) 
    std::__throw_out_of_range(__N("array::at")); 
return _M_instance[__n]; 
    } 
#endif 

यूएनडीईएफ मुख्य फ़ाइल में __EXCEPTIONS का हिस्सा है (या सरणी में #ifndef को #ifdef बदल) की ओर जाता है सही आउटपुट मुझे नहीं पता, यह सही समाधान है या नहीं, लेकिन यह काम करता है।

युपीडी: मैं

#ifdef __EXCEPTIONS 
    constexpr const_reference 
    at(size_type __n) const 
    { 
return __n < _Nm ? 
     _M_instance[__n] : (throw out_of_range(__N("array::at"))), 
          _M_instance[__n]; 
    /*return __n < _Nm ? 
      _M_instance[__n] : throw out_of_range(__N("array::at"));*/ 
    } 
#else 
    const_reference 
    at(size_type __n) const 
    { 
if (__n >= _Nm) 
    std::__throw_out_of_range(__N("array::at")); 
return _M_instance[__n]; 
    } 
#endif 

करने के लिए अपने सरणी के शीर्षक में कोड बदलने अब सब कुछ सही ढंग से काम कर रहा है

+8

प्रेषित शीर्षलेख में बग यह है कि '__n <_Nm? _M_instance [__ n]: out_of_range (__ n ("array :: at") फेंक दें) 'अस्थायी अस्थायी रूप से मूल्यांकन करता है (क्योंकि एक सशर्त ऑपरेटर को एक प्रक्षेपण का मूल्यांकन करना चाहिए यदि ऑपरेंड में से कोई एक 'फेंक' अभिव्यक्ति है - C++ 11 5.16/2)। यह अस्थायी जीवनकाल केवल 'वापसी' कथन (सी ++ 11 12.2/5) की पूर्ण अभिव्यक्ति के अंत तक है। तो 'at()' फ़ंक्शन किसी ऐसे व्यक्ति के लिए एक कॉन्स्ट संदर्भ देता है जो अब मान्य नहीं है - परिणाम अपरिभाषित व्यवहार है। –

+0

एक भयानक बग ('एक वापसी करें? बी: फेंक सी; ') --- यह नहीं सोचा होगा कि इस प्रकार की शुरुआती त्रुटि किसी भी भेजे गए सी ++ कंटेनर के साथ आता है। – Walter

+3

@MichaelBurr: मुझे लगता है कि यह अपने आप के जवाब के लायक हो सकता है! –