2012-01-30 17 views
6

this question का उत्तर देने के बाद और मानक पेपर में एक संतोषजनक उत्तर नहीं मिला, मैंने सोचना शुरू कर दिया। मानक निम्नलिखित w.r.t. बताता है उल्लेख चर का प्रारंभ:क्या ब्लॉक-स्कोप स्थिर या थ्रेड स्टोरेज अवधि चर के अंडरस्पेस्फीड के असफल प्रारंभ में गठित किया गया है?

§6.7 [stmt.dcl] p4

[...] नहीं तो इस तरह के एक चर आरंभ नहीं हो जाता पहली बार नियंत्रण अपनी घोषणा से होकर गुजरता है; इस तरह के चर को प्रारंभिकरण के पूरा होने पर प्रारंभ माना जाता है। यदि प्रारंभिक अपवाद फेंकने से निकलता है, तो प्रारंभिकता पूर्ण नहीं होती है, इसलिए अगली बार नियंत्रण घोषणा में प्रवेश करने की कोशिश की जाएगी।

कारण हो सकता है क्या हुआ अगर यह एक अपवाद फेंकने की तुलना में कुछ और से विफल रहा है (longjmp(), thead बाहर निकलें, संकेत कुछ नाम हैं) प्रारंभ पुनः प्रयास किया जाना का कोई उल्लेख नहीं है।

क्या मैंने मानक में कुछ भी नजरअंदाज किया? मैंने शुरुआतीकरण, घोषणा और अपवाद खंडों को देखा और यहां तक ​​कि "स्थिर" की त्वरित खोज के साथ CWG defects table of content से परामर्श लिया, लेकिन इससे संबंधित कुछ भी नहीं मिला।

क्या यह मानक में एक अंडरस्पेसिफिकेशन (और इस तरह के दोष के रूप में) है?

+1

क्या सी ++ सिग्नल से संबंधित _anything_ परिभाषित करता है? या 'longjmp'? थ्रेड निकास चीजों को बदल सकता है। –

+0

क्या आपके पास कोई ठोस परिदृश्य है कि आपको मानक द्वारा पर्याप्त रूप से निर्दिष्ट नहीं किया गया है? –

+0

@ केरेक: लिंक किया गया प्रश्न। : पी – Xeo

उत्तर

2

सी ++ विनिर्देश केवल सी ++ विनिर्देश के भीतर मौजूद चीजों को परिभाषित कर सकता है। याद रखें: सी ++ विनिर्देश परिभाषित वर्चुअल मशीन के व्यवहार को परिभाषित करता है। और यदि यह परिभाषित नहीं करता है कि कुछ हो सकता है, तो यह निश्चित रूप से ऐसा कुछ नहीं होने के बारे में सी ++ के व्यवहार को परिभाषित नहीं करता है।

सी ++ विनिर्देश के अनुसार, एक धागा बिल्कुल तीन तरीकों से बाहर निकल सकता है: अपने मुख्य कार्य से लौटकर, अपने मुख्य कार्य के माध्यम से अपवाद फेंकने और प्रत्यक्ष प्रक्रिया से बाहर निकलने (जैसे std::terminate या इसी तरह के कार्यों)। संक्षेप में, एक सी ++ धागा किसी भी अन्य तरीके से बाहर नहीं जा सकता है। मानक C++ में ExitThread फ़ंक्शन नहीं है। इसी तरह, std::thread बाहरी या आंतरिक रूप से धागे को मार नहीं सकता है।

इसलिए, ऐसा कुछ भी जो इस कारण का कारण बनता है कि सी ++ कहता है कि परिभाषा परिभाषित नहीं हो सकती है। मुझे लगता है कि यह "अपरिभाषित व्यवहार" भी नहीं होगा; यह उस घबराहट की जगह में होगा जो थ्रेडिंग सी ++ 11 से पहले था, वास्तव में थ्रेड इंटरैक्शन कैसे काम करता था।

वही "सिग्नल" के लिए जाता है, जो भी हो। सी ++ स्पेक यह नहीं कहता कि वे फ़ंक्शन से बाहर निकलने का कारण बन सकते हैं। खतरनाक इलाके।

longjmp के लिए, यह longjmp के व्यवहार से ढका हुआ है। जब आप फ़ंक्शन से बाहर निकलने के लिए longjmp का उपयोग करते हैं, तो वह फ़ंक्शन कभी समाप्त नहीं होता है, जैसे कि आपने throw और catch का उपयोग किया था। और सी ++ में, एक ऑब्जेक्ट केवल तभी बनाया जाता है जब उसका कन्स्ट्रक्टर पूरा हो गया हो। इसलिए वस्तु का प्रारंभिकरण कभी पूरा नहीं हुआ था, और यह अनियमित है।

मैं आईएसओ सी विनिर्देश (जो longjmp के व्यवहार के लिए सी ++ संदर्भ), लेकिन सी ++ 11 सुझाव है कि दृढ़ता से है कि आप कर सकते हैं समानता throw/catch साथ longjmp/setjmp, जब आप के रूप में जहाँ तक की जरूरत नहीं है अपरिभाषित व्यवहार:

§18.10 [support.runtime] p4: 

समारोह हस्ताक्षर longjmp (jmp_buf jbuf, पूर्णांक वैल) इस अंतर्राष्ट्रीय मानक में अधिक सीमित व्यवहार है। एक setjmp/longjmp कॉल जोड़ी ने अपरिभाषित व्यवहार किया है यदि setjmp और longjmp को कैच और फेंक से बदलना किसी भी स्वचालित ऑब्जेक्ट के लिए किसी भी गैर-तुच्छ विनाशकों को बुलाएगा।

इसलिए मुझे नहीं लगता कि यह अनिर्दिष्ट है। यह अच्छी तरह से और अच्छी तरह से निर्धारित नहीं किया जा सकता है, लेकिन सभी टुकड़े वहाँ हैं।

0

सिर्फ इसलिए कि पाठ का उल्लेख एक विशेष मामला है, यह चूकने से संकेत नहीं देता है कि अन्य कोई अलग होंगे। यदि प्रारंभ करने से प्रारंभ करने से रोकने के अन्य तरीके हैं, तो कार्यान्वयन को अगले निष्पादन पर पुनः प्रयास करना होगा।

मुझे लगता है कि निकोल का जवाब अधिकतर सही है, लेकिन एक गैर-तुच्छ कन्स्ट्रक्टर एक गैर-तुच्छ विनाशक को इंगित नहीं करता है। longjmp इसलिए प्रारंभिकरण को बाधित कर सकता है जैसे कि इसे पुनः प्रयास किया जाना चाहिए। यह केवल एक बहुप्रचारित वातावरण में मुश्किल है, जहां प्रारंभिक निष्पादित करने वाले पहले व्यक्ति बनने वाले धागे के बीच दौड़ की स्थिति को रोकने के लिए एक म्यूटेक्स की आवश्यकता होती है। प्रेत mutex ऑब्जेक्ट को एक गैर-तुच्छ विनाशक की आवश्यकता होती है भले ही प्रारंभिक ऑब्जेक्ट में कोई न हो। संभावित परिणाम डेडलॉक है। यह शायद डीआर के लिए अच्छी सामग्री है।

+0

यह नहीं है कि मानक केवल एक केस सूचीबद्ध करता है, यह केवल उस मामले के लिए * पुनः प्रयास * निर्दिष्ट करता है। यह नहीं कहता है "अगर विफल हुआ, अगली बार फिर से प्रयास करें"। यह विशेष रूप से कहता है "फेंकने * में असफल *, अगली बार फिर से प्रयास करें"। – Xeo

+0

@Xeo: बिलकुल नहीं। अगर प्रारंभिकता पूर्ण नहीं हुई, तो यह पहली जगह में प्रारंभिक नहीं था। पुनः प्रयास * पहली बार है। कि पिछला पाठ पहले से ही इस बात से तात्पर्य है कि यह भाषा द्वारा खुलासा किया गया है, "प्रारंभिकता पूर्ण नहीं है, ** इसलिए ** इसे फिर से प्रयास किया जाएगा ..." – Potatoswatter

+0

नहीं, ऐसा नहीं है, क्योंकि * * से पहले का पाठ केवल अपवादों का उल्लेख करता है। आप दोनों भागों को अलग नहीं कर सकते हैं। किसी भी मामले में, मुझे लगता है कि यह कम से कम एक स्पष्टीकरण के लिए एक अच्छा उम्मीदवार है। बीटीडब्ल्यू, म्यूटेक्स मुद्दे पर, मुझे लगता है कि पृष्ठ 138 पर यह पैर नोट लागू हो सकता है: "88) कार्यान्वयन प्रारंभकर्ता के निष्पादन के आसपास किसी भी डेडलॉक को लागू नहीं करना चाहिए।" – Xeo