2011-12-08 20 views
16

उदाहरण:सी ++ स्थिर प्रारंभ बनाम __attribute __ ((निर्माता))

struct Foo { Foo() { printf("foo\n"); } }; 
static Foo foo; 

__attribute__((constructor)) static void _bar() { printf("bar\n"); } 

यह foo या bar मौसम नियतात्मक है पहले छपा है?

(मुझे आशा है और उम्मीद करेंगे कि स्थिर वस्तुओं के निर्माताओं हमेशा निर्माता विशेषता इसके बारे में कुछ नहीं कहा के बारे में पहले नहीं बल्कि यकीन है कि और GCCs डॉक क्रियान्वित कर रहे हैं।)

+0

आप इस तरह के कंपाइलर सुविधाओं का उपयोग कहां करते हैं ?? – AlexTheo

+0

@AlexTheo: यह काफी आम है। उदाहरण देखें । जब भी आप कुछ प्रारंभ करना चाहते हैं तो आप आमतौर पर इसका इस्तेमाल करते हैं। – Albert

+0

असल में मैं स्थिर कॉन्स बूल _isInitialized जैसे कुछ पसंद करता हूं और एक निजी प्रारंभिक कार्य करता हूं जिसके साथ मैं अपनी ऑब्जेक्ट को कॉन्स्ट बूल MyClass :: _ isInitialized = initFunction(); लेकिन ये केवल उन वस्तुओं के लिए है जिन्हें मैं सबसे पहले शुरू करना चाहता हूं। अन्यथा कन्स्ट्रक्टर को नौकरी करना चाहिए। – AlexTheo

उत्तर

13

foo पहले प्रिंट किया जाएगा, के रूप में वस्तुओं को उनकी घोषणाओं के क्रम में शुरू किया जाता है। चलाने के लिए और देखें:

वैसे, __attribute__((constructor)) स्टैंडर्ड सी नहीं है ++। यह जीसीसी का विस्तार है। तो आपके कार्यक्रम का व्यवहार इस बात पर निर्भर करता है कि जीसीसी ने इसे कैसे परिभाषित किया है। संक्षेप में, यह कार्यान्वयन-परिभाषित है, इसके अनुसार foo पहले मुद्रित है।

doc कहते हैं, इससे पहले कि निष्पादन मुख्य प्रवेश करती है

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

आप ऑर्डर को नियंत्रित करने के लिए वैकल्पिक पूर्णांक प्राथमिकता प्रदान कर सकते हैं जिसमें निर्माता और विनाशक कार्य चल रहे हैं। एक बड़ी प्राथमिकता संख्या वाला एक कन्स्ट्रक्टर एक बड़ी प्राथमिकता संख्या वाले निर्माता के समक्ष चलता है; विपरीत संबंध विनाशकों के लिए है। इसलिए, यदि आपके पास एक ऐसा निर्माता है जो संसाधन और विनाशक को आवंटित करता है जो समान संसाधन को हटा देता है, तो दोनों कार्यों में आम तौर पर समान प्राथमिकता होती है। कन्स्ट्रक्टर और विनाशक कार्यों के लिए प्राथमिकताएं नामस्थान-स्कोप सी ++ ऑब्जेक्ट्स (सी ++ विशेषताएँ देखें) के लिए निर्दिष्ट हैं।

मैं बोल्ड में टेक्स्ट दर्शाता है लगता है, वस्तुओं, उनकी घोषणाओं के क्रम में प्रारंभ कर रहे हैं के रूप में मैं पहले भी कहा है, जो काफी भी online demo पुष्टि की है।

मुझे लगता है कि आप भी इस पढ़ने के लिए करना चाहते हैं:

आप नियंत्रित/आरंभीकरण आदेश को बदलने के लिए चाहते हैं, आप init_priority विशेषता का उपयोग कर सकते हैं, प्राथमिकता प्रदान करते हैं। the page से लिया:

Some_Class A __attribute__ ((init_priority (2000))); 
Some_Class B __attribute__ ((init_priority (543))); 

यहाँ, BA से पहले आरंभ नहीं हो जाता।

+0

एचएम, सभी टिप्पणियां हटा दी गयीं? वो कैसे संभव है। तो, यहां मेरी टिप्पणी दोबारा है: मेरे लिए दिलचस्प बात यह जानकारी थी कि आखिरी लिंक, एएसपी के साथ यह जानकारी मिल जाएगी। यह: * मानक सी ++ में, नेमस्पेस स्कोप पर परिभाषित ऑब्जेक्ट्स को किसी दिए गए अनुवाद इकाई में उनकी परिभाषाओं के अनुसार सख्ती से क्रम में प्रारंभ करने की गारंटी दी जाती है। * – Albert

+0

वास्तव में, मैंने अभी इसे किसी अन्य उदाहरण पर परीक्षण किया है, और यह ' ऐसा लगता है कि वहां मामला नहीं है। – Albert

+0

@ अल्बर्ट: कोड पोस्ट करें। वास्तविक कोड, इसे थोड़ा सा बदलने के बिना। आपको प्राप्त होने वाले आउटपुट को भी पोस्ट करें। – Nawaz

1

यह गैर-निर्धारिती प्रतीत होता है। जीसीसी के साथ संकलित होने पर मेरे प्रश्न में उदाहरण के आउटपुट के रूप में मेरे पास foo\nbar\n भी था। हालांकि, जब एलएलवीएम/क्लैंग के साथ संकलित किया गया, तो मुझे bar\nfoo\n मिल गया।

लेकिन, जैसा कि मुझे यकीन नहीं है कि यह क्लैंग में एक बग हो सकता है, मैंने एक बग रिपोर्ट here भर दी है। संपादित करें: मुझे वहां एक जवाब मिला और यह वास्तव में क्लैंग में एक बग प्रतीत होता है जो अभी तक तय नहीं हुआ है। यकीन नहीं है कि उस से क्या निष्कर्ष निकालना है। अपेक्षित और व्यवहार होना वास्तव में यहां निर्धारक है, हालांकि, आप इस पर निर्भर नहीं हो सकते हैं क्योंकि कम से कम एक प्रमुख कंपाइलर (क्लैंग) है जो गलत है (या जीसीसी से अलग है, अगर हम इसे के रूप में लेते हैं __attribute__((constructor)))।

ध्यान दें कि यह वास्तविक दुनिया कोड में वास्तव में प्रासंगिक और महत्वपूर्ण हो सकता है। जैसे here एक उदाहरण है जो एक यादृच्छिक जनरेटर बीज करता है जो क्लैंग के साथ विफल रहता है।

+0

इस पोस्ट को हटाएं। और अपना प्रश्न संपादित करें, और इसे वहां पोस्ट करें। एक जवाब एक जवाब होना चाहिए, एक प्रश्न नहीं। – Nawaz

+1

@ नवाज: आपका क्या मतलब है? क्यूं कर? यह एक जवाब है, मेरा सवाल एक सवाल है। यदि यह आपके लिए स्पष्ट नहीं है कि यह उत्तर उत्तर कैसे वास्तविक प्रश्न है: यह मूल रूप से कहता है कि यह अनिश्चित है। – Albert

+0

ठीक है। आप कैसे कह सकते हैं कि यह गैर-निर्धारिती है, और आप यह कैसे कह सकते हैं: "* तो, ऐसा लगता है कि rnd का निर्माता _rand_engine__init * के बाद निष्पादित किया गया है"। कुछ स्पष्टीकरण भी पोस्ट करें! – Nawaz