2012-02-01 16 views
5

मैं दो संकलन इकाइयों के साथ एक साझा लाइब्रेरी संकलित कर रहा हूं: globals.cpp और stuff.cppglobals.cpp फ़ाइल stuff.cpp में उपयोग किए जाने वाले बाहरी चर के कुछ मुट्ठी भर शुरू करती है। जिस समस्या का मैं अनुभव कर रहा हूं वह यह है कि stuff.cpp में कोड globals.cpp में कोड से पहले चल रहा है, बाहरी चरों को मान असाइन करने का अवसर मिला है। उदाहरण के लिए, मैं 0 मानों का एक गुच्छा देख रहा हूं। यह मुद्दा इस बात पर निर्भर करता है कि मैं कौन सा मंच संकलित/कोड चलाता हूं - कुछ काम और कुछ नहीं करते हैं।मेरा बाहरी चर अभी तक क्यों शुरू नहीं हुआ है?

कोई इसे हल करने के बारे में कैसे जाता है? क्या मैं globals.cpp को पर चला सकता हूं?

+3

आप [स्थैतिक प्रारंभिक आदेश फियास्को] [1] का अनुभव कर रहे हैं। [1]: http://stackoverflow.com/questions/3035422/static-initialization-order-fiasco – kfmfe04

+0

धन्यवाद, कम से कम इस मुद्दे को साफ़ करता है। – sholsapp

उत्तर

6

आप नहीं (एक सुसंगत तरीके से)

लेकिन आप इसे चारों ओर काम कर सकते हैं कर सकते हैं।

global.cpp

// If you have a global variable that has to be initial by a constructor 
MyObj globalX; 

// Instead do this 

MyObj& globalX() { static MyObj x; return x;} 

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

+0

इसने समस्या हल की। – sholsapp

2

comp.lang.C++ पूछे जाने वाले प्रश्न से, देखें:

+0

सामान्य रूप से अक्सर पूछे जाने वाले प्रश्न खराब सलाह देते हैं। पॉइंटर्स का उपयोग करना मतलब है कि वस्तुओं को लगातार नष्ट नहीं किया जाता है और विनाश के आदेश के साथ समस्याओं के बारे में अगला बिंदु सिर्फ सादा गलत है: http: // stackoverflow।कॉम/प्रश्न/335369/खोज-सी-स्थिर-प्रारंभिक-आदेश-समस्याएं # 335746 –

+0

@ लोकी एस्टारी: दिलचस्प। क्या यह पूरी तरह गलत है? एफएक्यू का उल्लेख है "यदि ए, बी और सी का उपयोग करने वाले उत्तरकर्ताओं के निर्माणकर्ताओं को सामान्य रूप से ठीक होना चाहिए क्योंकि रनटाइम सिस्टम स्थैतिक उन्मूलन के दौरान, उन तीनों वस्तुओं के आखिर में उत्तर नष्ट कर देगा।", हालांकि मैं मानता हूं कि यह इसके इतने बर्खास्त नहीं होना चाहिए। – jamesdlin

+0

वह किसी समस्या के रूप में लीकिंग को खारिज कर देता है क्योंकि ओएस द्वारा स्मृति साफ हो जाती है। यह सिर्फ ** मैला और बीएडी ** है। एक निर्माता/विनाशक के साथ कुछ भी तो यह वास्तव में स्मृति नहीं है; इन वस्तुओं के संसाधनों के बारे में और उनके साफ-सफाई के बारे में। इन वस्तुओं में कुछ भी हो सकता है और जब आप किसी ऑब्जेक्ट को संशोधित करते हैं तो क्या आप यह सुनिश्चित करने के लिए सभी जानकारियों को 'जानबूझकर रिसाव' करते हैं कि लीक आपके कोड की शुद्धता को प्रभावित नहीं कर रहा है (मुझे लगता है कि आप इन स्थानों को भी नहीं ढूंढ पाएंगे)। तो उनकी टिप्पणी प्रासंगिक होने का एकमात्र समय कन्स्ट्रक्टर/विनाशक के साथ सामान के लिए है। –

0

मैं आप इस behavious देख रहे हैं क्योंकि आप वैश्विक चर की इनलाइन प्रारंभ कर रहे हैं संभालने हूँ एक स्पष्ट समारोह कॉल के बिना। जैसे globals.cpp:

// top of source file 

#include "myincludes.h" 

CSomeClass someObject(432); 
int global_x = 42; 
int global_y = InitY(); 

वैश्विक वस्तुओं और वैश्विक चर प्रारंभ आदेश के निर्माता और नाशक आदेश ज्यादातर गैर नियतात्मक है। (मैं मानक संदर्भ पृष्ठों से परामर्श किए बिना अनुमान लगाऊंगा, स्रोत स्रोत में वेरिएबल्स शीर्ष घोषणा से नीचे तक प्रारंभ हो जाते हैं, लेकिन "कौन सी स्रोत फ़ाइल पहली बार आती है" का क्रम परिभाषित नहीं किया जाता है।)

सबसे अच्छा समाधान है किसी भी वैश्विक वस्तुएं नहीं हैं (जहां कन्स्ट्रक्टर लाइब्रेरी में किसी भी फ़ंक्शन से पहले चलाया जाता है) या वैश्विक परिवर्तनीय प्रारंभिक क्रम पर निर्भरता है।

एक ऐसा कार्य करने के लिए बेहतर है जो आपकी लाइब्रेरी को स्पष्ट रूप से प्रारंभ करता है। शायद आपको इस फ़ंक्शन को स्टार्टअप पर कॉल करने या अपनी लाइब्रेरी के निर्यात किए गए कार्यों को प्रारंभ करने का पता लगाने के बाद कॉल करने की आवश्यकता है। तब अपने ग्लोबल्स शुरू करें।

मेरी टीम पर, "मुख्य" (या "DllMain") से पहले चलाया गया कोड कड़ाई से अस्वीकार कर दिया गया है। दूसरे शब्दों में, कोई वैश्विक वस्तु नहीं है। ग्लोबल्स init करने के लिए कोई काम नहीं है।

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