2015-09-04 3 views
26

दो कार्यक्रमों को देखते हुए जहां स्रोत कोड में एकमात्र अंतर एक constexpr की उपस्थिति या अनुपस्थिति है, क्या यह संभव है कि कार्यक्रम का अर्थ बदल जाए?'constexpr' जोड़ना व्यवहार बदल सकता है?

दूसरे शब्दों में, यदि संकलक से constexpr का अनुमान लगाने के लिए वास्तव में कड़ी मेहनत करने के लिए संकलक से पूछने के लिए कोई संकलक विकल्प था, तो क्या यह मौजूदा मानक कोड तोड़ देगा और/या खराब तरीके से इसका अर्थ बदल देगा?

एक कोडबेस से निपटने की कल्पना करें जहां मूल डेवलपर constexpr को उन स्थानों पर शामिल करना भूल गया जहां संभव था, शायद सी ++ 11 से पहले कोड लिखा गया हो। यह अच्छा होगा अगर कंपाइलर आपके काम पर आने में मदद के लिए constexpr का अनुमान लगाएगा। बेशक, शायद यह हर बार इस धारणा के बारे में चेतावनी देना चाहिए, जिससे आप स्पष्ट रूप से constexpr को स्पष्ट रूप से जोड़ सकते हैं। लेकिन यह अभी भी उपयोगी होगा। मेरी चिंता यह है कि यह चीजों को तोड़ सकता है?

अब तक, केवल एक चीज मैं के बारे में सोच सकते हैं कि constexpr कार्यों परोक्ष inline हैं और स्थितियों inline जोड़ने बुरा तरीकों से चीजों को बदल सकते हैं, जहां हो सकता है; उदाहरण के लिए यदि आप एक-परिभाषा-नियम तोड़ते हैं।

+0

ठीक है, उदाहरण के लिए संकलक विक्रेताओं constexpr के रूप में मानक में चिह्नित नहीं कार्यों कि SFINAE के माध्यम से अलग व्यवहार का कारण बन सकता चिह्नित करने के लिए है, इसीलिए उसे था यह अंततः की अनुमति नहीं थी चुनते हैं, देखें [यह गैर के इलाज के लिए एक अनुरूप संकलक विस्तार है -constexpr मानक पुस्तकालय कार्यों को constexpr के रूप में?] (http://stackoverflow.com/q/27744079/1708801) –

+0

उस @ShafikYaghmour के लिए धन्यवाद। मैंने विचलन खोजने की कोशिश करने के लिए SFINAE के साथ कुछ प्रयोग किए थे, लेकिन मैं नहीं कर सका। मुझे लगता है कि मेरी उदाहरण भी साधारण :) –

+2

थे मैं एक है [एक उदाहरण यहां जहां SFINAE टूट जाता है] (http://stackoverflow.com/a/21319414/1708801) स्थिर भाव में अपरिभाषित व्यवहार के विभिन्न उपचार की वजह से। मुझे अभी भी कोई जवाब नहीं है कि क्या इसे अनुरूप माना जाता है या नहीं। बिल्कुल वही नहीं है लेकिन हम देख सकते हैं कि अलग-अलग कार्यान्वयन SFINAE को कैसे तोड़ सकते हैं। –

उत्तर

12

एक आसान चाल है।

विभिन्न कोड चलने के साथ, कोई भी व्यवहार परिवर्तन हो सकता है।

live example (बस बदलें कि #define X टिप्पणी की गई है)।उदाहरण के


डिजाइन:

char अधिभार बीमार का गठन किया जा रहा से ऊपर कोड से बचाता है, कोई निदान, आवश्यक के रूप में सभी टेम्पलेट्स एक वैध विशेषज्ञता होनी चाहिए। foo<char> आपूर्ति करता है कि। अभ्यास में, अपने अस्तित्व की आवश्यकता नहीं है: ADL बहुत दूर से एक foo, एक some_type* पर अतिभारित मिल सकता है, तो some_type*T के रूप में गुजरती हैं। जिसका मतलब है कि कोई संकलन इकाई साबित नहीं कर सकती कि कोड खराब हो गया था।

Ts... कि bar अधिभार कम-वरीय बनाता है। तो यदि पहला मैच मेल खाता है, तो कोई अस्पष्टता नहीं है। सिर्फ अगर पहले एक मैच के लिए विफल रहता है (एक SFINAE द्वारा foo(x)constexpr नहीं किया जा रहा की वजह से की वजह से) दूसरा अधिभार बुलाया प्राप्त करता है (या अगर, कहते हैं, किसी तर्क यह करने के लिए पारित कर दिया)।

+0

परफेक्ट करने के बारे में सावधान रहना चाहिए। मैं ऐसा कुछ करने के लिए संघर्ष कर रहा था जो क्लैंग और जी ++ दोनों में 'कॉन्टेक्सप्र'-निर्भर व्यवहार का प्रदर्शन करता था। लेकिन यह दोनों clang 3.5.0 और g ++ 5.2.0 के साथ चाल है। –

+0

.. मुझे लगता है कि इससे पता चलता है कि संकलित समय पर पता लगाना संभव हो सकता है कि कोई दिया गया कार्य 'constexpr' है या नहीं। हालांकि यह अच्छा लगता है, इसका मतलब है कि 'constexpr' का उल्लंघन करना खतरनाक होगा क्योंकि यह इन परीक्षणों के परिणाम को बदल देगा। अंत में, मुझे यह वास्तव में पसंद नहीं है, अब मैं इसे समझता हूं। मुझे लगता है कि यह एक त्रुटि देनी चाहिए - यदि सबसे अच्छा अधिभार 'constexpr' नहीं है, तो एक त्रुटि होनी चाहिए यदि इसे किसी संदर्भ में कहा जाता है जिसके लिए निरंतर अभिव्यक्ति की आवश्यकता होती है। (मेरी विनम्र राय में, बस पिछले कुछ मिनटों में गठित) –

+2

@AaronMcDaid त्रुटि तत्काल संदर्भ में है, इसलिए हमें किसी त्रुटि के बजाय प्रतिस्थापन विफलता मिलती है। SFINAE का अर्थ है कि लगभग किसी भी "हस्ताक्षर" परिवर्तन (यहां तक ​​कि अस्तित्व!) के परिणामस्वरूप सी ++ में एक अलग संकलन-समय और रन-टाइम व्यवहार हो सकता है, और किसी भी इंटरफ़ेस को लगभग पूरी तरह से अनुरूप बनाने के लिए असंभव बनाता है। हालांकि, यह मामला जहां होता है (हर मामले में मैंने इसे देखा है, ऊपर सहित) * पैथोलॉजिकल *। – Yakk

4

दो कार्यक्रमों जहां स्रोत कोड में फर्क सिर्फ इतना है उपस्थिति या एक constexpr का अभाव है को देखते हुए यह संभव है अर्थ प्रोग्राम परिवर्तनों का कि?

हाँ, यह कम से कम constexpr कार्यों के लिए सच है। यही कारण है कि कार्यान्वयन की अनुमति नहीं है कि कौन से मानक फ़ंक्शंस को कॉन्सएक्सप्रैर चिह्नित किया गया है, मुख्य मुद्दा यह है कि उपयोगकर्ता SFINAE के माध्यम से विभिन्न व्यवहार देख सकते हैं। यह LWG issue 2013: Do library implementers have the freedom to add constexpr? में दर्ज है जो कहते हैं (जोर मेरा):

कुछ चिंता का विषय है जब वोट WP स्थिति के लिए पूर्ण समिति के समक्ष प्रस्तुत किया है कि इस मुद्दे के बिना अपसारी के लिए परिणाम के लिए पर्याप्त सोचा हल किया गया था व्यक्त लाइब्रेरी कार्यान्वयन, क्योंकि उपयोगकर्ता अन्यथा समान कोड से अलग व्यवहार का निरीक्षण करने के लिए SFINAE का उपयोग कर सकते हैं। समस्या वापस समीक्षा स्थिति में ले जाया गया, और एक बड़े समूह के साथ पोर्टलैंड में फिर से चर्चा की जाएगी। पोर्टलैंड के लिए नोट: जॉन स्पाइसर एलडब्ल्यूजी के भीतर ऐसी किसी भी चर्चा के दौरान कोर की चिंताओं का प्रतिनिधित्व करने पर सहमत हो गया है।

template<int n>struct i{}; 
int foo(int){return 0;} 
constexpr int foo(char){return 'a';} 

template<class T=int, T x=1,i<foo(x)>* =nullptr> 
bool bar(){return true;} 
template<class T=int, T x=1,class...Ts> 
bool bar(Ts...){return false;} 

अगर int foo(int), constexpr है bar का एक अलग अधिभार डिफ़ॉल्ट रूप से चुना जाता है:

+1

@AaronMcDaid मैं वास्तव में एक लाइव उदाहरण बनाने की कोशिश कर रहा हूं, यह थोड़ी देर के बाद से मैंने उस कोड को देखा और मैं यह सुनिश्चित करना चाहता हूं कि मेरे पास विवरण सही हैं। –

+0

यह विशिष्ट में 'constexpr' कार्यों के लिए सच है। इसके अलावा, 'constexpr' के अन्य उपयोग भी हैं, इसलिए मैं कहूंगा कि यह आंशिक रूप से सच है। – edmz

+0

(मैंने अभी इस उत्तर पर बनाई गई एक पूर्व टिप्पणी को हटा दिया है, क्योंकि मैं अभी तक इसका उपयोग करने में सक्षम नहीं हूं, जहां एक 'constexpr'' की उपस्थिति के कारण व्यवहार में परिवर्तन होता है) –

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