2

我正在处理严重依赖于语言标准中描述的异常规范行为的旧代码。即,在违反下述形式的异常规范时调用 std::unexpected()。

foo() throw(T) { /*...*/ }

Nothrow 规范确实保证不会抛出,但是throw(T)规范预计会被设计和……所违反,因为标准期望同样多,并提供了一种处理它的机制。

其原因与设计人员决定使用 EH 作为除异常处理之外的错误处理机制(由其自己的错误类层次结构控制)有关。EH 中呈现的成语与他们的需求密切相关,他们采取了最省力的方式。考虑到系统的规模和复杂性,这至少是我的看法,而且对我来说并不是特别令人震惊。

然而,我现在的任务是包含新的和不相关的功能,并且由于与 8.0 中引入的异常规范相关的标准存在偏差,因此代码在 VC++ 9.0 下的行为与预期不同。(参考:微软

我试图找到一种强制标准行为的方法。希望编译器提供后备。但是没有。

我是否运气不好,需要更改在 350,000 行代码上运行的正确编写的符合标准的代码,并具有完全开发的错误处理类层次结构?或者你能想出一种方法来帮助我强制 std::unexpected() 行为吗?

编辑: 我提供了一些背景信息。有问题的系统是一个学年日历生成器,为一所学校服务,分布在 4,000 多名学生中,我不确定其中的一些数字,6 个年级和约 190 个班级,外加 12 个虚拟(远程教学)类。MINGW 与 VC++ 8.0 或 9.0 以外的任何编译器一样,都是不可能的。这是由于有关为该国教育系统服务的软件的规定。

代码所需的更改正是为了适应虚拟类的引入,这些虚拟类具有用于日历生成的截然不同的模式。然后我碰到了这个问题。该软件在日历生成过程的几个部分大量使用异常机制,作为通过意外()映射(保存和恢复)和 bad_exception 映射来控制工作流的一种手段,这些映射都不能在 VC++ 下工作。就纯粹个人而言,我发现该机制实际上非常优雅,即使完全不常见。但我离题了。

4

2 回答 2

4

我不相信 Visual C++ 异常规范行为曾经(或声称已经)符合标准 - 甚至在 8.0 之前 - 所以我不确定应用程序是如何工作的。

执行以下更改是否可行:

void f() throw(T)
{
    // ...
}

到:

void f()
{
    try
    {
        // ...
    }
    catch (T)
    {
        throw;
    }
    catch (...)
    {
        app_unexpected();
    }
}
于 2009-09-12T21:09:58.410 回答
1

正如您所提到的,Visual Studio 有一种处理异常规范的“有趣”方式:

  • throw()有其正常含义(函数不能抛出)
  • 其他任何东西(包括无异常规范)都被解释为throw(...)

没有办法规避这一点。然而,C++ 社区非常同意异常规范是无用的。你真的需要运行时检查抛出的错误类型吗?也许适当的单元测试可以代替您的运行时检查。

于 2009-09-12T21:28:15.377 回答