You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MSVC编译器忽略C++ throw语句 异常不触发问题排查求助

问题根因

  • 第一个问题:你代码中onCreate里的空throw;属于未定义行为,该语法仅允许在catch块内部使用,用于重抛当前捕获的异常,在无异常上下文执行时MSVC默认会直接忽略该语句。
  • 第二个核心问题:窗口过程属于操作系统回调函数,Windows的DispatchMessage内部默认会吞掉所有从窗口过程抛出的C++异常,不会向上传递到消息循环或main函数,MSVC严格遵循Windows平台的异常处理约定,因此不会触发程序终止,MinGW的默认运行时配置未遵循该约定所以不会出现这个现象。
  • 第三个隐藏问题:你没有初始化COM库就调用CoCreateInstance,该接口调用必然返回失败,就算异常正常抛出也会触发异常逻辑。

修复步骤

  1. 修正编译配置
    打开项目属性页,定位到「C/C++ -> 代码生成 -> 启用C++异常」,确认配置为是(/EHsc),不要选择关闭异常的配置项。如果需要同时捕获结构化异常,可选择是,但有SEH异常(/EHa)。

  2. 修正非法throw语句
    将空throw;替换为合法的异常抛出语句,例如throw "测试异常";。

  3. 窗口过程增加异常捕获
    在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;
    }
}
  1. 初始化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 13:48:04