MSVC编译器忽略C++ throw语句 异常不触发问题排查求助
问题根因
- 第一个问题:你代码中
onCreate里的空throw;属于未定义行为,该语法仅允许在catch块内部使用,用于重抛当前捕获的异常,在无异常上下文执行时MSVC默认会直接忽略该语句。 - 第二个核心问题:窗口过程属于操作系统回调函数,Windows的
DispatchMessage内部默认会吞掉所有从窗口过程抛出的C++异常,不会向上传递到消息循环或main函数,MSVC严格遵循Windows平台的异常处理约定,因此不会触发程序终止,MinGW的默认运行时配置未遵循该约定所以不会出现这个现象。 - 第三个隐藏问题:你没有初始化COM库就调用
CoCreateInstance,该接口调用必然返回失败,就算异常正常抛出也会触发异常逻辑。
修复步骤
修正编译配置
打开项目属性页,定位到「C/C++ -> 代码生成 -> 启用C++异常」,确认配置为是(/EHsc),不要选择关闭异常的配置项。如果需要同时捕获结构化异常,可选择是,但有SEH异常(/EHa)。修正非法throw语句
将空throw;替换为合法的异常抛出语句,例如throw "测试异常";。窗口过程增加异常捕获
在SimpleWindow::windowProc的最外层增加try-catch块,主动捕获抛出的异常并自定义处理逻辑,示例如下:
LRESULT CALLBACK SimpleWindow::windowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { try { // 原有窗口过程的全部代码放在此处 Content__ *obj = (Content__*)GetWindowLongPtrA(hwnd,GWLP_USERDATA); // ... 其余原有代码 } catch (const char* err) { // 自定义异常处理逻辑,例如输出日志、弹出提示、退出程序 OutputDebugStringA(err); PostQuitMessage(-1); return 0; } catch (...) { OutputDebugStringA("捕获到未知异常\n"); PostQuitMessage(-1); return 0; } }
- 初始化COM库
在main函数最开头增加COM库初始化代码,程序退出前反初始化:
int main() { // 新增COM初始化,注意选择和你的线程模型匹配的参数 CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); Content content; SimpleWindow win(&content,"",640,480); while(win.isOpen()) { auto &msg = win.getMessage(); win.dispatchMessage(msg); } // 新增COM反初始化 CoUninitialize(); return 0; }
内容的提问来源于stack exchange,提问作者user13947194
相关产品推荐
相关产品推荐

