2009-10-08 6 views
5

मैं क्यूटी कोडिंग सम्मेलनों डॉक्स पढ़ने और निम्नलिखित पैराग्राफ पर आया था:सी ++ स्थिर वैश्विक गैर-पॉड: सिद्धांत और व्यवहार

कुछ भी एक निर्माता है या प्रारंभ करने के लिए कोड को चलाने के लिए की जरूरत है कि नहीं किया जा सकता लाइब्रेरी कोड में वैश्विक ऑब्जेक्ट के रूप में, क्योंकि यह कन्फर्मर/कोड चलाया जाएगा (पहले उपयोग पर, लाइब्रेरी लोड पर, मुख्य() या से पहले पर नहीं)। यहां तक ​​कि यदि प्रारंभिक पुस्तकालयों के लिए प्रारंभकर्ता का निष्पादन समय परिभाषित किया गया है, तो प्लगइन में उस कोड को स्थानांतरित करते समय या लाइब्रेरी को स्थिर रूप से संकलित करते समय आपको परेशानी होगी।

मुझे पता है कि theory कहता है, लेकिन मुझे "बिलकुल नहीं" भाग समझ में नहीं आता है। कभी-कभी मैं गैर-पीओडी ग्लोबल कॉन्स स्टेटिक्स (उदाहरण: क्यूस्ट्रिंग) का उपयोग करता हूं और यह कभी मेरे लिए नहीं हुआ कि उन्हें प्रारंभ नहीं किया जा सकता है ... क्या यह साझा वस्तुओं/डीएलएल के लिए विशिष्ट है? क्या यह केवल टूटे हुए कंपाइलरों के लिए होता है?

इस नियम के बारे में आप क्या सोचते हैं?

+0

यदि आप उनका उपयोग नहीं करते हैं तो आपका क्यूस्ट्रिंग प्रारंभ नहीं किया जा सकता है। लेकिन अगर आप उनका इस्तेमाल करते हैं तो उन्हें शुरू किया जाएगा। भले ही यह उपयोग से पहले है (यानी वस्तु पर एक mthod कहा जाता है)। –

उत्तर

8

"बिलकुल नहीं" भाग बस इतना कहता है कि सी ++ मानक इस मुद्दे के बारे में चुप है। यह साझा पुस्तकालयों के बारे में नहीं जानता है और इस प्रकार कुछ सी ++ सुविधाओं के साथ बातचीत के बारे में कुछ भी नहीं कहता है।

व्यवहार में, मैं वैश्विक गैर-पॉड स्थिर Windows, OSX और लिनक्स और अन्य Unices के कई संस्करणों पर इस्तेमाल वैश्विक, दोनों जीयूआई और कमांड लाइन कार्यक्रमों में देखा है, प्लग इन के रूप और स्टैंडअलोन अनुप्रयोगों के रूप में। कम से कम एक परियोजना (जो गैर-पीओडी स्थैतिक ग्लोबल्स का उपयोग करती है) में इन सभी संयोजनों के पूर्ण सेट के लिए संस्करण थे। मैंने कभी देखा है कि एकमात्र समस्या यह थी कि कुछ पुराने जीसीसी संस्करण उत्पन्न कोड जो गतिशील पुस्तकालयों में ऐसी वस्तुओं के dtors कहा जाता है जब निष्पादन योग्य बंद कर दिया, जब पुस्तकालय unloaded था। बेशक, यह घातक था (लाइब्रेरी कोड बुलाया गया था जब पुस्तकालय पहले से ही चला गया था), लेकिन यह लगभग एक दशक पहले हुआ है।

लेकिन बेशक, यह अभी भी कुछ भी गारंटी नहीं देता है।

2

मुझे नहीं लगता कि स्थिर वस्तुओं के रचनाकारों को elided किया जा सकता है। संभवतः इस तथ्य के साथ एक भ्रम है कि एक स्थिर पुस्तकालय अक्सर ऑब्जेक्ट्स का एक गुच्छा होता है जो निष्पादन योग्य में टोकन होता है यदि उनका संदर्भ दिया जाता है। कुछ स्थिर वस्तुओं को डिज़ाइन किया गया है ताकि उन्हें उनके युक्त ऑब्जेक्ट के बाहर संदर्भित न किया जा सके, और इसलिए ऑब्जेक्ट फ़ाइल केवल निष्पादन योग्य में रखी जाती है यदि उनके पर एक और निर्भरता हो। यह कुछ पैटर्न में नहीं है (एक स्थिर वस्तु का उपयोग करके जो उदाहरण के लिए खुद को पंजीकृत करता है)।

+0

मुझे लगता है कि आप "स्थैतिक पुस्तकालय" के साथ "स्थैतिक वस्तु" को भ्रमित कर रहे हैं। – sbi

+1

"स्थैतिक वस्तुओं" से मेरा मतलब था "स्थिर भंडारण अवधि वाले ऑब्जेक्ट्स"। बीटीडब्लू, मुझे संदर्भ मिला है कि अगर उन्हें प्रारंभिक या विनाशक का दुष्प्रभाव होता है तो उन्हें हटाया नहीं जा सकता है: 3.7.1/2। – AProgrammer

+0

मेरा मतलब था कि स्थिर पुस्तकालयों की संभावना सबसे अधिक संभावना नहीं है। यह गतिशील पुस्तकालय है जो समस्या है। – sbi

2

यदि स्थैतिक वस्तु किसी ऑब्जेक्ट में परिभाषित की जाती है जिसे संदर्भित नहीं किया जाता है, तो लिंकर स्थिर प्रारंभिक कोड सहित ऑब्जेक्ट को पूरी तरह से प्रोब्यून कर सकता है। यह libs के लिए नियमित रूप से ऐसा करता है (इस प्रकार gnc के तहत इसके हिस्सों का उपयोग करते समय libc पूरी तरह से लिंक नहीं होता है, उदाहरण के लिए)।

दिलचस्प बात यह है कि मुझे नहीं लगता कि यह पुस्तकालयों के लिए विशिष्ट है। यह शायद मुख्य निर्माण में वस्तुओं के लिए भी हो सकता है।

2

मुझे रचनाकारों के साथ वैश्विक वस्तुओं के साथ कोई समस्या नहीं दिखती है।

उन्हें अपने रचनाकार (या विनाशक) में अन्य वैश्विक वस्तुओं पर निर्भरता नहीं होनी चाहिए।

लेकिन यदि उनके पास निर्भरता है तो आश्रित वस्तु को या तो एक ही संकलन इकाई में होना चाहिए या आलसी मूल्यांकन किया जाना चाहिए ताकि आप इसे उपयोग करने से पहले इसका मूल्यांकन करने के लिए मजबूर कर सकें।

निर्माता में कोड भी जब (इस निर्भरता से संबंधित है, लेकिन से भिन्न) यह क्रियान्वित किया जाता है पर निर्भर नहीं होना चाहिए, लेकिन आप ग्रहण करने के लिए कम से कम है कि यह निर्माण किया जाएगा सुरक्षित हैं (बस से पहले एक विधि कहा जाता है) और सी ++ गारंटी देता है कि विनाश आदेश तत्काल के विपरीत है।

इन नियमों के साथ रहना इतना मुश्किल नहीं है।

2

सी ++ आदेश है कि स्थिर initializers अलग संकलन इकाइयों में वस्तुओं के लिए निष्पादित (आदेश में अच्छी तरह से एक संकलन इकाई के भीतर परिभाषित किया गया है) को परिभाषित नहीं करता।

उस स्थिति पर विचार करें जहां आपके पास 2 स्थिर वस्तुएं ए और बी विभिन्न संकलन इकाइयों में परिभाषित हैं। आइए मान लें कि ऑब्जेक्ट बी वास्तव में ऑब्जेक्ट ए का प्रारंभिकरण में उपयोग करता है।

इस परिदृश्य में यह संभव है कि बी पहले शुरू किया जाएगा और एक प्रारंभिक ऑब्जेक्ट के खिलाफ कॉल करें। यह एक चीज हो सकती है जिसका अर्थ है "बिलकुल नहीं" - एक ऑब्जेक्ट का उपयोग किया जा रहा है जब उसे इसे पहले शुरू करने का मौका नहीं मिला है (भले ही इसे बाद में शुरू किया जा सके)।

मुझे लगता है कि गतिशील जोड़ने जटिलताओं कि मुझे लगता है कि के बारे में सोचा नहीं किया है एक वस्तु प्रारंभ कभी नहीं करने के लिए cuase जोड़ सकते हैं लगता है। किसी भी तरह से, नीचे की रेखा यह है कि स्थैतिक प्रारंभिक भूलभुलैया पर्याप्त संभावित मुद्दों का परिचय देती है जहां इसे संभवतः से बचा जाना चाहिए और जहां आपको इसका उपयोग करना है, बहुत सावधानीपूर्वक संभाला जाना चाहिए।

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