C++/MFC try catch 异常捕获不到

本文探讨了在VC编译器中,当选择代码优化选项时,try-catch结构可能被误判为多余并被优化掉的问题。文章指出,在Release模式下,若try块内无throw语句,编译器可能会移除try-catch结构,导致异常无法被捕获,进而使程序异常退出。解决方案是使用__try,__except结构或在编译命令行中加入/EHa参数。

try

{

BYTE *pch;

pch = (BYTE *)01234; //非法地址

 

*pch = 5;

}

catch (...)

{

AfxMessageBox("捕获异常");

}

 

但在Release方式下如果选择了编译器代码优化选项,则 VC编译器会去搜索try块中的代码, 如果没有找到throw代码,他就会认为try catch结构是多余的, 给优化掉。上述代码中的异常不能被捕获,从而迫使程序弹出错误提示框退出。

 

如改成__try, __except结构,异常即可捕获。

 

而是Windows平台特有的扩展。如果在使用过程中涉及局部对象析构函数的调用,则会出现C2712 的编译错误。

 

仍然使用C++标准的try{}catch(..){}, 在编译命令行中加入 /EHa 的参数。VC编译器不会把try catch模块给优化掉。

 

Project->Seting->C/C++ Project Options: 添加 /EHa

<think>在C++中,特别是在MFC(Microsoft Foundation Classes)环境下,使用try-catch捕获函数执行错误需要注意一些特殊机制。MFC中主要使用两种异常处理方式:C++标准异常MFC自定义的异常宏(如TRY, CATCH等)。但现代MFC应用程序推荐使用C++标准的try/catch。 然而,MFC中有些异常不是从std::exception派生的,比如CException及其派生类(如CMemoryException, CFileException等)。因此,在MFC程序中捕获函数执行错误时,需要同时考虑这两种情况。 以下是一个示例,展示如何捕获MFC函数可能抛出的异常: ```cpp #include <afx.h> // MFC核心头文件 void MyFunction() { // 可能抛出异常MFC函数调用 CFile file; if (!file.Open(_T("test.txt"), CFile::modeRead)) { // 通常MFC函数通过返回错误或抛出异常来报告错误,具体取决于函数实现。 // 对于CFile::Open,它会抛出CFileException异常。 // 所以这里我们不需要返回错误,因为如果失败会抛出异常。 } // 其他操作 } int main() { try { MyFunction(); } catch (CException* e) // 捕获MFC异常(注意是指针形式) { TCHAR szError[1024]; e->GetErrorMessage(szError, 1024); // 输出错误信息 _tprintf(_T("MFC异常: %s\n"), szError); e->Delete(); // 必须删除异常对象 } catch (const std::exception& e) // 捕获标准库异常 { // 处理标准异常 _tprintf(_T("标准异常: %s\n"), CString(e.what())); } catch (...) { // 捕获其他所有异常 _tprintf(_T("未知异常\n")); } return 0; } ``` 关键点: 1. MFC异常通常以指针形式抛出(如`CException*`),捕获后需要调用`Delete()`方法删除异常对象(这是MFC的机制)。 2. 同时,我们也要捕获标准库异常(如std::exception)和其他未知异常。 注意:在MFC中,旧式的异常处理宏(如TRY, CATCH, THROW等)已经被C++标准的try/catch取代,因此推荐使用标准的try/catch。 另外,在MFC中,有些函数可能通过返回状态码来表示错误,而不是抛出异常。因此,需要根据具体函数的文档来确定错误处理方式。 如果函数是通过返回错误码,那么我们可以这样处理: ```cpp BOOL bSuccess = functionThatReturnsErrorCode(); if (!bSuccess) { // 处理错误,可能通过抛出异常或记录日志等 AfxThrowUserException(); // 如果需要抛出异常 } ``` 但是,在MFC中,很多函数在内部会调用AfxThrow...系列函数来抛出异常,所以使用try-catch是必要的。 总结:在MFC捕获函数执行错误,应使用标准的try-catch块,并特别注意捕获CException*类型的异常,并在处理完后删除异常对象。 §§相关问题§§ 1. MFC中CException类的派生类有哪些,分别代表什么错误? 2. 在MFC捕获CException指针后,为什么必须调用Delete方法? 3. 如何将MFC异常(CException)转换为标准异常(std::exception)? 4. 在MFC应用程序中,如何全局捕获未处理的异常?</think>### 在 C++/MFC 中使用 `try-catch` 捕获函数执行错误 在 MFC (Microsoft Foundation Classes) 中捕获函数执行错误时,需要特别注意 MFC 特有的异常机制和错误处理模式: #### 核心实现方法 ```cpp #include <afx.h> void RiskyMfcFunction() { // MFC 函数可能抛出 CException 派生类异常 CFile file; if (!file.Open(_T("data.txt"), CFile::modeRead)) { // 手动抛出文件异常 AfxThrowFileException(CFileException::fileNotFound); } // 其他可能抛出异常MFC操作 } int main() { try { RiskyMfcFunction(); // 调用可能出错的函数 } catch (CException* e) // 捕获MFC异常(指针形式) { TCHAR szError[256]; e->GetErrorMessage(szError, 256); AfxMessageBox(szError); // 显示错误消息 e->Delete(); // 必须删除异常对象! } catch (...) // 兜底捕获所有其他异常 { AfxMessageBox(_T("未知错误发生")); } return 0; } ``` #### 关键注意事项 1. **MFC 异常类型**: - 所有 MFC 异常都继承自 `CException`(如 `CFileException`, `CMemoryException`) - 捕获时使用 `catch (CException* e)`(指针形式) 2. **必须的资源清理**: ```cpp e->Delete(); // 必须调用,否则内存泄漏 ``` 3. **错误信息获取**: ```cpp TCHAR szError[256]; e->GetErrorMessage(szError, 256); // 获取可读错误信息 ``` 4. **MFC 特有函数**: - `AfxThrowFileException()`:手动抛出文件异常 - `AfxMessageBox()`:显示错误对话框 - `TRACE()`:调试输出错误信息 #### 最佳实践 1. **区分异常类型**: ```cpp catch (CFileException* fe) { // 处理文件异常 } catch (CMemoryException* me) { // 处理内存异常 } ``` 2. **资源安全释放**: ```cpp CFile file; try { file.Open(...); // 文件操作 } catch (CException* e) { if (file.m_hFile != CFile::hFileNull) file.Close(); // 确保资源释放 e->Delete(); } ``` 3. **结合返回值检查**: ```cpp if (!UpdateData(TRUE)) { // MFC对话框数据交换 AfxThrowUserException(); // 手动抛出用户异常 } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值