https://blog.csdn.net/shiqw5696/article/details/80664749

前段时间写了一篇关于C++异常捕获及异常处理的文章:
c++异常捕获及异常处理try-throw-catch

严格的来说,那不算是一篇完整的文章,更多的是提出我的疑惑。顺便总结了一下网友关于C++异常捕获及异常处理给出的精炼的示例。

至今,上文提到的疑惑本菜鸟都没有完全解开。

于是,我就选择了用 __try __except 来捕获及处理异常。经过测试,我想捕获的异常用 __try __except 都捕获到了,相当开心。

但是,今天在用 __try __except 的时候蹦出来一个让我既苦恼又兴奋的错误:

error C2712: 无法在要求对象展开的函数中使用__try

本能的打开百度,输入错误提示,一顿查找,并没有找到很好理解的解释。于是我求救 google ,终于找到了我能很容易理解的解释。(哎,小学语文没学好就是吃亏)

首先,我们来看几个会报C2712错误的示例:

#include <string>

inline std::string foo() { return "abc"; }
inline int foo2() { return ; } class MyClass
{
public:
MyClass() { m_val = ; }
MyClass(int param) { m_val = param; }
~MyClass(); int GetVal() { return m_val; } private:
int m_val;
}; void TestTryExcept_1()
{
using namespace std;
string str = ""; // 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();
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 ;

上述代码在编译的时候会报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 修改一下:

 void TestTryExcept_1()
{
using namespace std;
string str = "";
printf_s("TestTryExcept_1: %s\n", str.c_str());
} void TestTryExcept_2()
{
using namespace std;
printf_s("TestTryExcept_2: %s\n", foo());
} void TestTryExcept_3()
{
MyClass ObjA();
int ret = ObjA.GetVal();
printf_s("TestTryExcept_3: %d\n", ret);
} int _tmain(int argc, _TCHAR* argv[])
{
        // 类对象的创建 不能和__try__except在同一个函数中
        //using namespace std;
        //string str = "main, string object";
        //printf_s("%s\n", str);          __try
{
TestTryExcept_1();
TestTryExcept_2();
TestTryExcept_3();
}
__except (EXCEPTION_EXECUTE_HANDLE)
{
printf_s("__except\n");
} getchar();
return ;

大家可以看到,上述修改后的代码还存在一个问题,就是在 main 中使用了__try __except 后,就无法创建类对象,也就是像 string 这样的类就无法使用了,要不然就会报错。

所以我们再修改一下,把 main 拆成两个函数:

 void TestTryExcept_all()
{
__try
{
TestTryExcept_1();
TestTryExcept_2();
TestTryExcept_3();
}
__except (EXCEPTION_EXECUTE_HANDLE)
{
printf_s("__except\n");
}
} int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
string str = "main, string object";
printf_s("%s\n", str); TestTryExcept_all(); getchar();
return ;
}

这样,所有问题就解决啦。

纯手打,如果有什么问题,欢迎各位大佬指出。

好了,我给大佬递茶去了。。。

声明:上述代码未包含所有需要的头文件,请大家自行脑补。

参考:

Compiler Error C2712

very simple code, and getting error C2712, could not understand why

版权声明

如需转载请注明来源和作者,谢谢!!

本文链接:https://blog.csdn.net/ShiQW5696/article/details/80664749

[C++]“error C2712: 无法在要求对象展开的函数中使用__try”解决方案的更多相关文章

  1. VS2010:“error C2712: 无法在要求对象展开的函数中使用 __try”

    ZC:这个错误是在使用 "__try{...} __except(EXCEPTION_EXECUTE_HANDLER){}"时 遇到的 http://blog.csdn.net/c ...

  2. 无法在要求对象展开的函数中使用 __try

    解决方案: 单独把try里面的代码封装成一个函数,然后再在try里面调用

  3. error LNK2019: 无法解析的外部符号 该符号在函数 中被引用 解决方案

    需要添加lib或者dll库.项目-属性-配置属性-链接器-输入-附件依赖项,添加需要的lib. 例如我在运行OSG程序的时候,忘记添加了附件依赖项就会报这个错. 解决方案如图.

  4. handler.post 为什么要将thread对象post到handler中执行呢?

    转载网址:http://www.cnblogs.com/crazypebble/archive/2011/03/23/1991829.html在Android中使用Handler和Thread线程执行 ...

  5. 转:handler.post 为什么要将thread对象post到handler中执行呢?

    转载网址:http://blog.csdn.net/fei0724/article/details/8664462在Android中使用Handler和Thread线程执行后台操作 对于线程的控制,我 ...

  6. ECMASCript2015 提案 stage-3的对象展开运算符

    看源码时看到如下的代码 export default { //通过mapActions将actions映射到methods里 methods: { ...mapActions([ 'updateSta ...

  7. 当时用vuex的时候,使用...对象展开扩展符报错的解决办法

    出现这种问题的主要原因是当前的babel不支持...对象展开扩展符,只需要安装一个插件然后再在.babelrc当中进行下配置就好了 npm i babel-plugin-transform-objec ...

  8. [转] Vuex入门(2)—— state,mapState,...mapState对象展开符详解

    1.state  state是什么? 定义:state(vuex) ≍ data (vue) vuex的state和vue的data有很多相似之处,都是用于存储一些数据,或者说状态值.这些值都将被挂载 ...

  9. error C2712: Cannot use __try in functions that require object unwinding

    转自VC错误:http://www.vcerror.com/?p=52 问题描述: error C2712: Cannot use __try in functions that require ob ...

随机推荐

  1. 网上的很多Android项目源码有用吗?Android开发注意的地方。

    在Android项目开发中,我们可以在网上看到很多项目源码,大部分也不是很精致, 比如 06.Android阿福多媒体播放器开发教程+源码 还有什么浏览器源码. 那么这些有用吗?  价值在哪里? 精致 ...

  2. Codeforces.1051G.Distinctification(线段树合并 并查集)

    题目链接 \(Description\) 给定\(n\)个数对\(A_i,B_i\).你可以进行任意次以下两种操作: 选择一个位置\(i\),令\(A_i=A_i+1\),花费\(B_i\).必须存在 ...

  3. OI常用重载运算符

    用STL时经常用到 PS:这里有个巨坑,把重载写在STL里常数会爆炸,分分钟大数据TLE 所以就把重载放在结构体里啦 //以priority_queue的重载为例 //priority_queue默认 ...

  4. 摆脱CSS浏览器私有属性-moz, -ms, -webkit

    为了兼容各个浏览器之间的私有属性,前端开发人员在写css的时候需要给一些css属性添加多个私有前缀,非常麻烦.这里给大家分享一个简单的方法可以让你以后无需手动给CSS添加私有属性. -moz代表fir ...

  5. [USACO18DEC]Cowpatibility

    Description: Farmer John 的 \(N\) 头奶牛(\(2\le N\le 5\times 10^4\))各自列举了她们最喜欢的五种冰激凌口味的清单.为使这个清单更加精炼,每种可 ...

  6. 20172310 实验四 Android程序设计

    20172310 2017-2018-2 <程序设计与数据结构>实验四报告 课程:<程序设计与数据结构> 班级: 1723 姓名: 仇夏 学号:20172310 实验教师:王志 ...

  7. [jzoj]1417.数学题

    Link https://jzoj.net/senior/#main/show/1417 Problem 当Alice在浏览数学书时,看到一个等式A=S,奇怪的是A和S并不相等.Alice发现可以通过 ...

  8. NodeJS 模块&函数

    NodeJS 模块&函数 nodejs的多文件操作通过模块系统实现,模块和文件一一对应.文件本身可以是javascript代码.JSON或编译过的C/C++扩展 基本用法 nodeJS通过ex ...

  9. js中call和apply的作用和用法

    call和apply的用途是完全一样的.改变函数中this的指向: 为什么要改变this的指向呢?这个有什么用?有哪些场景呢? 首先this的指向总是在变的,this的指向是由函数执行时所在的环境决定 ...

  10. html-webpack-plugin插件使用chunks属性时报错

    报错如下图: 原因是之前template属性使用的html模板内添加了script标签,将其删掉再使用chunks属性自动添加即可. (注释掉也不可以,必须删除!)