2011-04-11 9 views
8

मैं मुख्य समारोह में ढेर पर कुछ वस्तुओं है स्थानीय वस्तुओं का विनाशकर्ता फोन:आवेदन समाप्त कर देंगे और

void Err(std::string msg) 
{ 
    SomehowLogErrorMessage(msg); 
    exit(1); 
} 
:

int main(...) 
{ 
    CFoo foo; 
    CBar bar; 
} 

इसके अलावा, मैं एक समारोह, कि अपने आवेदन में त्रुटियों का ट्रैक रखता है

त्रुटि कार्य निश्चित रूप से उपयोगी होता है जब मुझे घातक त्रुटि की रिपोर्ट करना पड़ता है। मैं सिर्फ त्रुटि लॉग करता हूं और एप्लिकेशन को समाप्त करता हूं - यह ऐसी त्रुटियों के बाद पुनर्प्राप्त नहीं हो सकता है। हालांकि, "निकास()" के साथ समाप्त होने से foo और bar destructors - एक व्यवहार नहीं है, जिसे मैं वास्तव में उम्मीद करता था (लेकिन गलत था)। "abort()" या तो मदद नहीं करता है। इसके अलावा, मैं मुख्य() में उन्हें पकड़ने के लिए अपवाद का उपयोग नहीं कर सकता। क्या एरर फ़ंक्शन को लागू करने का कोई अन्य तरीका है, ताकि यह ऐप को समाप्त कर दे और स्टैक ऑब्जेक्ट को सही तरीके से साफ़ कर सके? या क्या मुझे किसी भी तरह से मेरी त्रुटि हैंडलिंग को फिर से डिजाइन करना चाहिए?

धन्यवाद!


पेज। वैसे, क्या मैं अपनी मुख्य विंडो में WM_QUIT संदेश नहीं भेज सकता? मैं WinAPI के साथ अच्छा नहीं हूं, लेकिन मेरा ऐप शुद्ध Win32 है और मेरा एरर() फ़ंक्शन मेरी मुख्य विंडो में हैंडल प्राप्त कर सकता है। क्या ये काम करेगा?

+2

स्पष्ट, बेवकूफ सवाल, लेकिन आप अपवादों का उपयोग क्यों नहीं कर सकते? – forsvarir

+0

यदि आप कोई अपवाद नहीं फेंक सकते हैं (क्यों नहीं?) दूसरा विकल्प एक त्रुटि कोड वापस करना है, और उसके बाद मुख्य के अंत तक सभी तरह से प्रसारित करना है। –

+0

मान लें, प्लेटफ़ॉर्म-विशिष्ट प्रतिबंध। परियोजना को ध्वज-अपवाद ध्वज के साथ संकलित किया गया है। – SadSido

उत्तर

3

अपवाद के बिना या सामान्य रूप से कॉलस्टैक तक एरर से वापस लौटने के बिना। आपको ढेर को खोलने की जरूरत है।

0

मेरा मानना ​​है कि Exit तुरंत आवेदन समाप्त कर देगा। जिस व्यवहार की आप उम्मीद कर रहे हैं उसे देखने के लिए foo और bar को दायरे से बाहर जाना होगा। इसका मतलब है कि मुख्य कार्य को रिटर्न वैल्यू के साथ सामान्य रूप से समाप्त करना होगा। अपने एरर फ़ंक्शन से Exit() पर कॉल करने के बजाय आपको अपने मुख्य फ़ंक्शन पर वापस जाने का तरीका ढूंढने की आवश्यकता है और इसे सामान्य रूप से त्रुटि मान के साथ वापस जाने दें।

2

अभी भी सी का setjmp और longjmp है। यह आपको main पर वापस लाएगा, इसलिए कार्यक्रम main के दायरे को छोड़ने के बाद सामान्य के रूप में समाप्त हो जाएगा, इस स्थिति में सी ++ की विनाशक तंत्र main में आपकी स्थानीय वस्तुओं को नष्ट कर देगा।

बेशक longjmp का उपयोग कर अच्छे कारणों से सी ++ में फंस गया है। यह किसी भी अन्य कार्यों को ढेर पर छोड़ देगा, इसलिए यह वास्तव में main में कुछ स्टैक ऑब्जेक्ट्स के लिए काम करता है।

ढेर पर अपनी ऑब्जेक्ट आवंटित करना और delete मैन्युअल रूप से Err में आवंटित करना आसान हो सकता है।

+0

ट्रोलिंग के लिए खेद है और एआरआर और मुख्य के बीच भी छोड़ें (आवश्यकता में नहीं ?:-) –

+0

अच्छा, यह भयानक होगा, लेकिन कम से कम यह हमें मुख्य() में वापस ले जाएगा ... मैं वास्तव में फिर से- यदि मैं हैकिंग के बजाय ओपी था तो मेरी त्रुटि प्रबंधन को डिज़ाइन करें। –

+0

मुझे नहीं लगता कि यह कहना सुरक्षित है कि सी रनटाइम फ़ंक्शन विनाशकों को कॉल करेगा। यहां तक ​​कि मैनपेज का कहना है कि रजिस्टर और स्वचालित चर के मानों को अपरिभाषित नहीं किया जाएगा। –

1

सी ++ में त्रुटियों को प्रसारित करने के लिए मूल रूप से दो विधियां हैं: अपवाद (जिसे आपने मनमाने ढंग से बहिष्कृत किया है) और कोड लौटाते हैं।

चूंकि आप अपवादों का उपयोग नहीं कर सकते हैं, इसलिए आपको अपने कार्यों से रिटर्न कोड पास करना शुरू करना होगा जो विफल हो सकते हैं और यह देखने के लिए जांच कर सकते हैं कि आपको रोकने की आवश्यकता है या मुख्य पर वापस लौटना है या नहीं। यदि आप इस तरह के ढेर को अनदेखा नहीं करते हैं तो यह गारंटी देने का कोई तरीका नहीं है कि विनाशकों को ठीक से बुलाया जाएगा।

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

+0

ठीक है, कार्यक्रम घातक स्थिति में नहीं है (कुछ भी दूषित नहीं है)। लेकिन बाद का काम व्यर्थ है, इसलिए मैं यहां और अभी बाहर निकलने का रास्ता तलाश रहा था। और मैं अनावश्यक रिटर्न-वैल्यू-चेक-एंड-प्रोपेगेट कोड के एक पैक से बचने की उम्मीद कर रहा था ... – SadSido

+4

दूसरे शब्दों में, "मैं बिल्कुल अपवादों की पेशकश करना चाहता हूं, लेकिन मैं अपवादों का उपयोग नहीं कर सकता" – Novelocrat

+0

यह वही है जो मैं करता हूं – SadSido

0

मैं आपकी त्रुटि प्रबंधन को फिर से डिजाइन कर दूंगा। करने के लिए सबसे सरल चीज main पर नियंत्रण नियंत्रण है, और इसे सामान्य सफाई करने दें। अपवाद इस क्षमता को अवांछित ढेर के माध्यम से प्रदान करते हैं, लेकिन आप अपवादों का उपयोग नहीं कर सकते हैं। हॉ, वह ठीक है। कभी-कभी आप अपवादों का उपयोग नहीं कर सकते हैं।

तो Err होने की बजाय प्रोग्राम को बंद करने का प्रयास करें, Err त्रुटि लॉग करें और एक त्रुटि कोड लौटें। आदर्श रूप से, Err वैसे भी दो नौकरियां नहीं करनी चाहिए, जिसे आप इसे करने का प्रयास कर रहे हैं: 1) त्रुटि लॉग करें, 2) ऐप को गहराई से समाप्त करें।

यदि आपका आवेदन बहुप्रचारित होता है, तो आप असफल हो सकते हैं। त्रुटि-लॉगिंग थ्रेड में, "मरने" ईवेंट को सिग्नल करें। इस घटना पर मुख्य धागा प्रतीक्षा करें जो इसके साथ इंतजार कर रहा है (या QueueUserAPC या इसी तरह के माध्यम से इसे नौकरी इंजेक्ट करें)। जब ईवेंट सिग्नल किया जाता है, तो ऐप को बंद कर दें।

+0

चाहते हैं जो मुझे कॉल स्टैक तक सभी तरह से त्रुटि कोड का विश्लेषण करने के लिए मजबूर करेगा। यही वह है जिसे मैं टालने की कोशिश कर रहा था, अब मुझे लगता है कि सी ++ के लिए यह असंभव है। बदतर, एरर() ऑब्जेक्ट कन्स्ट्रक्टर के अंदर बुलाया जा सकता है - और मैं वहां से त्रुटि कोड कैसे पारित कर सकता हूं? – SadSido

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