https://blog.csdn.net/shiqw5696/article/details/80664749c++
前段時間寫了一篇關於C++異常捕獲及異常處理的文章:
c++異常捕獲及異常處理try-throw-catch函數
嚴格的來講,那不算是一篇完整的文章,更多的是提出個人疑惑。順便總結了一下網友關於C++異常捕獲及異常處理給出的精煉的示例。測試
至今,上文提到的疑惑本菜鳥都沒有徹底解開。ui
因而,我就選擇了用 __try __except 來捕獲及處理異常。通過測試,我想捕獲的異經常使用 __try __except 都捕獲到了,至關開心。this
可是,今天在用 __try __except 的時候蹦出來一個讓我既苦惱又興奮的錯誤:google
error C2712: 沒法在要求對象展開的函數中使用__tryspa
本能的打開百度,輸入錯誤提示,一頓查找,並無找到很好理解的解釋。因而我求救 google ,終於找到了我能很容易理解的解釋。(哎,小學語文沒學好就是吃虧).net
首先,咱們來看幾個會報C2712錯誤的示例:code
#include <string> inline std::string foo() { return "abc"; } inline int foo2() { return 612; } class MyClass { public: MyClass() { m_val = 0; } MyClass(int param) { m_val = param; } ~MyClass(); int GetVal() { return m_val; } private: int m_val; }; void TestTryExcept_1() { using namespace std; string str = "666"; // string 是一個類,銷燬對象時會調用析構函數,因此會報錯 __try { // Do anything } __except (EXCEPTION_EXECUTE_HANDLE) { printf_s("__except\n"); } // string str; // 不管放在函數裏的什麼位置都會致使 C2712 錯誤 } void TestTryExcept_2() { using namespace std; // foo()返回的是臨時的string對象, // 也就是說,調用foo()時,會生成一個臨時的string變量存放返回的數據 // 本質上和TestTryExcept_1()是同樣的 foo(); // 和 TestTryExcept_1() 同樣使用了 string 類 // string retStr = foo(); __try { // Do anything } __except (EXCEPTION_EXECUTE_HANDLE) { printf_s("__except\n"); } } void TestTryExcept_3() { // 使用了本身定義的類也會報錯,由於銷燬對象時一樣會調用析構 MyClass ObjA(612); int ret = ObjA.GetVal(); __try { printf_s("__try: %d\n", ret); } __except (EXCEPTION_EXECUTE_HANDLE) { printf_s("__except\n"); } } int _tmain(int argc, _TCHAR* argv[]) { TestTryExcept_1(); TestTryExcept_2(); TestTryExcept_3(); return 0; }
上述代碼在編譯的時候會報C2712錯誤,緣由在代碼註釋中簡單註明了。對象
其實緣由就是:
在使用 __try __except 的函數中任何位置(測試的幾個位置都會報錯,若有描述錯誤請告知)建立了類對象就會致使C2712編譯錯誤。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
msdn上給出的描述和解決方案
Compiler Error C2712
cannot use __try in functions that require object unwinding
When you use /EHsc, a function with structured exception handling cannot have objects that require unwinding (destruction).
Possible solutions:
Move code that requires SEH to another function
Rewrite functions that use SEH to avoid the use of local variables and parameters that have destructors. Do not use SEH in constructors or destructors
Compile without /EHsc
Error C2712 can also occur if you call a method declared by using the __event keyword. Because the event might be used in a multithreaded environment, the compiler generates code that prevents manipulation of the underlying event object, and then encloses the generated code in an SEH try-finally statement. Consequently, error C2712 will occur if you call the event method and pass by value an argument whose type has a destructor. One solution in this case is to pass the argument as a constant reference.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
咱們來將上面三個函數和 main 修改一下:
1 void TestTryExcept_1() 2 { 3 using namespace std; 4 string str = "666"; 5 printf_s("TestTryExcept_1: %s\n", str.c_str()); 6 } 7 8 void TestTryExcept_2() 9 { 10 using namespace std; 11 printf_s("TestTryExcept_2: %s\n", foo()); 12 } 13 14 void TestTryExcept_3() 15 { 16 MyClass ObjA(612); 17 int ret = ObjA.GetVal(); 18 printf_s("TestTryExcept_3: %d\n", ret); 19 } 20 21 int _tmain(int argc, _TCHAR* argv[]) 22 { 23 // 類對象的建立 不能和__try__except在同一個函數中 24 //using namespace std; 25 //string str = "main, string object"; 26 //printf_s("%s\n", str); 27 28 __try 29 { 30 TestTryExcept_1(); 31 TestTryExcept_2(); 32 TestTryExcept_3(); 33 } 34 __except (EXCEPTION_EXECUTE_HANDLE) 35 { 36 printf_s("__except\n"); 37 } 38 39 getchar(); 40 return 0; 41 }
你們能夠看到,上述修改後的代碼還存在一個問題,就是在 main 中使用了__try __except 後,就沒法建立類對象,也就是像 string 這樣的類就沒法使用了,要否則就會報錯。
因此咱們再修改一下,把 main 拆成兩個函數:
1 void TestTryExcept_all() 2 { 3 __try 4 { 5 TestTryExcept_1(); 6 TestTryExcept_2(); 7 TestTryExcept_3(); 8 } 9 __except (EXCEPTION_EXECUTE_HANDLE) 10 { 11 printf_s("__except\n"); 12 } 13 } 14 15 int _tmain(int argc, _TCHAR* argv[]) 16 { 17 using namespace std; 18 string str = "main, string object"; 19 printf_s("%s\n", str); 20 21 TestTryExcept_all(); 22 23 getchar(); 24 return 0; 25 }
這樣,全部問題就解決啦。
純手打,若是有什麼問題,歡迎各位大佬指出。
好了,我給大佬遞茶去了。。。
聲明:上述代碼未包含全部須要的頭文件,請你們自行腦補。
參考:
Compiler Error C2712
very simple code, and getting error C2712, could not understand why
版權聲明
如需轉載請註明來源和做者,謝謝!!
本文連接:https://blog.csdn.net/ShiQW5696/article/details/80664749