gpt4 book ai didi

c++ - 为什么用新语法 `noexcept` 重写旧的空抛出规范?

转载 作者:行者123 更新时间:2023-11-27 22:33:00 25 4
gpt4 key购买 nike

标题说明了一切:为什么 C++ 放弃了非常令人满意的、有用的、空抛出规范 throw() 以用另一种语法取而代之,并引入了新关键字 noexcept?

空抛出规范是“只抛出这些枚举的异常保证”(写成throw(X,Y,Z)),但枚举的异常为零:而不是抛出XYZ(和派生类型),您可以抛出空集:这是函数永远不会抛出任何东西的保证调用者,换句话说,永不抛出或“不抛出”规范

无偿地使用基本相同的工具编写新代码,表达相同的 promise ,与旧代码不兼容,旧代码被弃用然后被禁止,无缘无故地破坏了向后兼容性?

是什么导致了对 throw() 的如此憎恨?

据我所知,只有旧的不安全的 gets 和愚蠢无用的隐式 int 被严厉对待。

编辑:

所谓的“重复”是基于虚假陈述。

在所谓的“动态异常规范”中没有任何“动态”的东西。这是我最讨厌新的抛出规范的地方:反对“动态”和“静态”。

最佳答案

That gratuitously made new code using essentially the same tool, expressing the same promise, incompatible with old code

更正:如果函数违反动态异常规范,std::unexpected被调用,它调用默认调用 std::terminate 的意外处理程序.但是处理程序可以用用户函数代替。如果函数违反了 noexcept , std::terminate直接调用。

promise 不同。 throw()意思是“如果它试图发出异常,可能会做意想不到的事情”。 noexcept意思是“如果它试图发出异常,将立即终止。”

只有在 C++17 中 throw()完全等同于 noexcept .这是在 6 年的异常规范(包括 throw())被弃用之后。

需要注意的是 unexpected first papers about noexcept 中明确引用了差异.具体来说:

Note that the usefulness of noexcept(true) as an optimization hint goes way beyond the narrow case introduced by N2855. In fact, it goes beyond move construction: when the compiler can detect non-throwing operations with certainty, it can optimize away a great deal of code and/or data that is devoted to exception handling. Some compilers already do that for throw() specifications, but since those incur the overhead of an implicit try/catch block to handle unexpected exceptions, the benefits are limited.

隐含的 try/catch block 是必需的,因为 unexpected必须在将堆栈展开到 throw() 之后调用功能。本质上,每个 throw()函数看起来像这样:

void func(params) throw()
try
{
<stuff>
}
catch(...)
{
std::unexpected();
}

所以当一个异常试图离开一个throw()函数,异常被捕获并且堆栈展开。更重要的是,每个 throw()函数必须内置异常机制。所以无论花费多少try/catchthrow() 都会产生区 block 功能。

在第一个版本noexcept ,发出异常是直接的 UB,而后来的版本切换为 std::terminate .但即便如此,也无法保证平仓。所以实现可以实现 noexcept以更有效的方式。当系统在堆栈中查找最近的 catch子句,如果它触及 noexcept 的底部功能,它可以直接终止而无需任何捕获机制。

What caused such hate of throw()?

更正:不重新利用构造并不意味着恶意。尤其是当发明一种新结构可以避免兼容性破坏时,如上所示。

需要注意的是throw()被认为等同于 noexcept根据 noexcept 的功能表达。也就是说,调用 throw()函数不会抛出异常,并且 noexcept(empty_throw())表达式将导致 true .

还应注意,无论如何都需要一个新关键字。为什么?因为throw(<stuff>)在 C++98/03 中已经有了意义。 noexcept(<stuff>)对于 <stuff> 具有非常不同的含义.试图把 noexcept throw里面的东西从解析的角度来看,说明符会……很困难。

另外,您现在可以将这个新关键字用作通用表达式:noexcept(<expression>)解析为 true如果其中的所有调用都不会抛出异常。这允许您根据事物是否会抛出异常来执行条件逻辑。你需要一个新的关键字来做类似的事情(或者你必须制作丑陋的语法,而 C++ 有太多这样的事情发生)。

关于c++ - 为什么用新语法 `noexcept` 重写旧的空抛出规范?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58576026/

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