यदि आप असेंबली कोड जेनरेट करते हैं, तो यह स्पष्ट हो जाता है कि क्या हो रहा है। निम्नलिखित सी ++ कोड:
hDevice = CreateFileA(path, // drive to open
// etc...
);
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
throw runtime_error(error_message());
}
(कम से कम डिफ़ॉल्ट अनुकूलन का उपयोग करके) विधानसभा कोड का एक खंड उत्पन्न करता है:
call [email protected] #
LEHE4:
sub esp, 28 #,
mov DWORD PTR [ebp-12], eax # hDevice, D.51673
cmp DWORD PTR [ebp-12], -1 # hDevice,
jne L5 #,
mov DWORD PTR [esp], 8 #,
call ___cxa_allocate_exception # // <--- this call is made between the
# // CreateFile() call and the
# // error_message() call
mov ebx, eax # D.50764,
lea eax, [ebp-16] # tmp66,
mov DWORD PTR [esp], eax #, tmp66
LEHB5:
call __Z13error_messagev #
आप एक कॉल करने के लिए बनाया ___cxa_allocate_exception
देखने के अपवाद के लिए कुछ स्मृति ब्लॉक आवंटित करने के लिए फेंके । वह फ़ंक्शन कॉल GetLastError()
स्थिति बदल रहा है।
जब सी ++ कोड लगता है:
hDevice = CreateFileA(path, // drive to open
// etc...
);
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
const string msg = error_message();
throw runtime_error(msg);
}
तो आप निम्नलिखित उत्पन्न विधानसभा मिलती है:
call [email protected] #
sub esp, 28 #,
mov DWORD PTR [ebp-12], eax # hDevice, D.51674
cmp DWORD PTR [ebp-12], -1 # hDevice,
jne L5 #,
lea eax, [ebp-16] # tmp66,
mov DWORD PTR [esp], eax #, tmp66
call __Z13error_messagev #
LEHE4:
sub esp, 4 #,
mov DWORD PTR [esp], 8 #,
call ___cxa_allocate_exception # // <--- now this happens *after*
// error_message() has been called
जो विफल रहा है CreateFile()
कॉल और error_message()
करने के लिए कॉल के बीच एक बाहरी फ़ंक्शन को कॉल नहीं करता ।
इस तरह की समस्या कुछ वैश्विक स्थिति जैसे GetLastError()
या errno
का उपयोग करके त्रुटि प्रबंधन के साथ मुख्य समस्याओं में से एक है।
यदि आप 'error_message (GetLastError())' कॉल करने के लिए अपना कोड संशोधित करते हैं तो क्या होता है? –
आप निश्चित रूप से महसूस करते हैं कि "GetLastError()", C++ कोशिश/पकड़ अपवाद, और Win32 "संरचित अपवाद हैंडलिंग" (एसईएच) सभी तीन अलग-अलग (संबंधित, लेकिन अलग) चीजें हैं, है ना? आप आम तौर पर एक या दूसरे का उपयोग करते हैं, लेकिन आप * एक दूसरे के साथ संयोजन के साथ * आम तौर पर * एक साथ * का उपयोग नहीं करना चाहिए। – paulsm4
@GregHewgill मैं GetLastError() को छिपाना चाहता हूं, और मैं इसके बजाय error_message() का उपयोग करना चाहता हूं। – Ali