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