gpt4 book ai didi

c++ - 遗留代码在析构函数中抛出异常

转载 作者:行者123 更新时间:2023-11-28 04:16:27 25 4
gpt4 key购买 nike

我正在维护相当旧的遗留代码。我的先行者开创了异常处理(<2000)。处理非标准行为的 throw 和 catch 逻辑似乎有效。

他们实现了一种很好的 throw 方式:

TL_THROW_EXCEPTION(ISQL_MSG_XML_PARSER_ERROR) << msg; 

TL_THROW_EXCEPTION 扩展为:

TLThrowTec::CTLThrowExceptionTechnical::ThrowT(__FILE__,__LINE__, 
ISQL_MSG_XML_PARSER_ERROR) << msg;

它在堆栈上创建一个 TLThrowTec::CTLThrowExceptionTechnical 实例,使用移位操作来设置消息字符串。析构函数创建并抛出异常。

stackoverflow 中 2008 年的条目解释了当年的状态: throwing exceptions out of a destructor那时它似乎奏效了。

但是现在 Visual Studio 17 允许抛出,但不能再捕捉了。

由于遗留代码是整个系统的一部分,因此它会生成日志文件条目,例如“未处理的操作系统异常”。

我想在不对源代码进行太多更改的情况下恢复捕获逻辑。最好为 TL_THROW_EXCEPTION 使用 #define。

有没有办法重新定义宏,以便在消息中抛出异常?

如果我搜索 TL_THROW_EXCEPTION,这是最后一行:

匹配行:770 匹配文件:217 搜索的文件总数:3159

我不喜欢触摸所有这些。

最佳答案

现代 C++ 默认将所有析构函数指定为非抛出。如果任何指定为非抛出的函数抛出异常,程序将立即终止。这是因为抛出析构函数是不受欢迎的。在堆栈展开期间自动调用析构函数,而异常已经在传输中。在这种情况下,再次 throw 本身将终止程序。如果所包含对象的析构函数抛出异常,所有标准容器都会发出 UB 警告。

但是您的用例不容易触发任何这些。 ThrowT 对象在我看来意味着被创建为立即抛出某些东西的临时对象,它们不会徘徊在其他东西的堆栈展开期间调用它们的析构函数。因此,我们可以将它们标记为再次抛出以恢复功能。像这样的……

ThrowT::~ThrowT() noexcept(false) {
// as before
}

...将使宏再次工作。

关于c++ - 遗留代码在析构函数中抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56490802/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com