2015-03-04 12 views
5

घोषित करने की आवश्यकता है मैंने पाया है कि इंटेल कंपाइलर std :: array ऑब्जेक्ट्स के लिए रिटर्न वैल्यू ऑप्टिमाइज़ेशन उत्पन्न नहीं करता है। निम्न कोड, जो मेरे प्रोग्राम के आंतरिक लूप में होता है, अनुकूलित नहीं किया जा सकता है।क्या रिटर्न वैल्यू ऑप्टिमाइज़ेशन को कॉपी कॉपी कन्स्ट्रक्टर

std::array<double, 45> f(const std::array<double, 45>& y) { 
    auto dy_dt = std::array<double, 45>(); 
    ... 

    return dy_dt; 
} 

मैं पता लगा है कि इस व्यवहार तथ्य यह है कि मेरी मानक पुस्तकालय कार्यान्वयन स्पष्ट रूप से std :: सरणी के लिए एक प्रतिलिपि निर्माता को परिभाषित नहीं करता से आता है। निम्नलिखित कोड को दर्शाता है कि:

class Test { 
public: 
    Test() = default; 
    Test(const Test& x); 
}; 

Test f() { 
    auto x = Test(); 

    return x; 
} 

जब आप इसके साथ

icpc -c -std=c++11 -qopt-report=2 test.cpp -o test.o 

रिपोर्ट फाइल से पता चलता

INLINE REPORT: (f(Test *)) [1] main.cpp(7,10) 

जो साबित करता है कि संकलक उत्पन्न करता RVO संकलन (च के हस्ताक्षर बदल गया है इसलिए यह कॉलिंग साइट के ढेर पर नव निर्मित ऑब्जेक्ट डाल सकता है)। लेकिन आप लाइन है कि Test(const Test& x); वाणी बाहर टिप्पणी करता है, तो, रिपोर्ट फ़ाइल

INLINE REPORT: (f()) [1] main.cpp(7,10) 

जो साबित करता है कि RVO उत्पन्न नहीं कर रहा है पता चलता है।

आरवीओ को परिभाषित करने वाले सी ++ 11 मानक के 12.8.31 में, उनके द्वारा दिए गए उदाहरण में एक प्रतिलिपि है। तो, क्या यह इंटेल कंपाइलर का एक "बग" है या मानक के अनुरूप कार्यान्वयन है?

+0

@ साइबर नंबर, यदि आरवीओ संभव था तो यह प्रतिलिपि को पूरा करेगा। – juanchopanza

+0

साइबर: नहीं, इसे यहां वापस मूल्य मूल्य अनुकूलन नाम दिया गया है। इसके चलते अर्थशास्त्र के साथ कुछ लेना देना नहीं है। – InsideLoop

+0

आरवीओ को एक प्रतिलिपि प्रतिलिपि की आवश्यकता नहीं है, लेकिन जिस कोड के लिए आरवीओ लागू होगा, वह वैध प्रतिलिपि या कन्स्ट्रक्टर को उपलब्ध होने की आवश्यकता है। – juanchopanza

उत्तर

1

यह प्रोग्राम एक परिभाषा नियम के उल्लंघन के कारण, बिना किसी निदान के अनिश्चित व्यवहार का कारण बनता है।

एक प्रति-निर्माता odr-used मूल्य - even if copy elision takes place द्वारा लौटने पर है।

एक गैर-इनलाइन फ़ंक्शन odr-used का अर्थ है कि फ़ंक्शन की बिल्कुल एक परिभाषा प्रोग्राम में दिखाई देनी चाहिए। हालांकि आपने कोई भी प्रदान नहीं किया है, और कॉपी-कन्स्ट्रक्टर की आपकी घोषणा संकलक-जेनरेट की गई परिभाषा को दबा देती है।

+0

मुझे लगता है कि यह शायद इसलिए है क्योंकि सभी कोड दिखाए गए नहीं हैं। उन्होंने या तो मुख्य प्रदान नहीं किया है। Hypothetically, एक और फ़ाइल test2.cpp हो सकता है, दिखाया या उल्लिखित नहीं है, जिसमें उस प्रतिलिपि निर्माता की परिभाषा है। या यह main.cpp में हो सकता है। – thang

+0

@ मैट: मुझे आपकी बात समझ में नहीं आ रही है। यदि आप एक कॉपी कन्स्ट्रक्टर को परिभाषित नहीं करते हैं, तो मानक आपके लिए एक को परिभाषित करता है। – InsideLoop

+0

@InsideLoop no; यदि आप एक कॉपी-कन्स्ट्रक्टर * घोषित नहीं करते हैं, तो संकलक आपके लिए एक घोषित करता है और परिभाषित करता है। साथ ही, जैसा कि इथेन इंगित करता है, यदि आप एक वैध प्रोग्राम (या एक प्रयास) पोस्ट करते हैं तो यह उपयोगी होगा। आप किसी ऐसे प्रोग्राम के आधार पर ऑप्टिमाइज़ेशन बग रिपोर्ट दर्ज नहीं कर सकते जो संकलित नहीं करता है। –

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