问题标签 [exception-specification]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
1417 浏览

c++ - g++ 可以检查抛出说明符吗?

关于这个的两个问题:

  • 有没有办法强制g++忽略说明throw符?
    (例如,我记得,Visual Studio 忽略了 throw 说明符,不同于throw()

  • 是否可以强制g++检查 throw 说明符是否正确 - 我的意思是检查(这可以通过一次性编译器完成)是否具有 throw 说明符的函数调用函数,这可能只是通过观看他们的 throw说明符注意执行throw异常,这会违反说明符吗?(注意:这不应该在没有 throw 说明符的情况下观看函数,因为这可能会导致大量警告)


编辑:我将为我的第二个问题添加一些示例。

假设我们有:

0 投票
3 回答
3321 浏览

java - Try/Catch 或 IF 处理丢失的文件?

尝试/捕获异常或使用 if 语句来处理不同的结果更好吗?

为了方便,我正在用 Java 编写一个简短的程序来复制文件,并使用 ifs 来处理文件不存在的事件,并为每个方法声明 throws,但不要使用 try/catch。

我应该返回并用 try/catch 替换那些 if 和相关部分,还是这种“可接受的”编程“用于与一小群用户共享?

0 投票
2 回答
4122 浏览

c++ - std::runtime_error::runtime_error(const std::string&) 如何满足 std::exception 对 throw() 的要求?

std::exception要求它的构造函数是throw(). 然而,std::runtime_error接受 astd::string作为它的参数,这表明它在std::string某处存储 a。因此,必须在某处进行分配或复制构造。而对于std::string,这不是一个nothrow操作。

那怎么会runtime_error::runtime_errorthrow()

(对于上下文,我正在实现一个异常类型,并且想std::string从调用站点存储几个 s,并且我想正确地做到这一点......)

0 投票
2 回答
3474 浏览

c++ - C++11 中默认的虚拟析构函数的异常规范是什么?

假设我有:

默认析构函数的异常规范是什么?默认析构函数是否等效于:

C++11 标准的 15.4 节说它取决于析构函数的隐式定义直接调用的函数的异常规范。在这种情况下,没有成员,也没有基类,因此 AFAIK 没有由隐式析构函数直接调用的函数。这是标准中的歧义(或遗漏)吗?

当然,这很重要,因为如果它隐式具有 throw(),那么所有子类都必须使用 throw() 声明它们的析构函数。不要告诉我在析构函数中抛出异常是个坏主意,我知道。我处理了许多根本没有使用异常规范的遗留代码。

作为一个信息点,当我尝试时:

我在 GCC 4.4 中遇到了一个错误(不匹配的异常规范)(尽管我承认我可能没有正确的命令行开关),但在使用“11”编译器的 XCode 4.3 中却没有。

0 投票
2 回答
1029 浏览

c++ - “set_unexpected”在 VC2010 中不起作用?

我正在使用 VC2010,并编写以下代码来测试“set_unexpected”功能。

但是,从未调用过“my_unexpected_handler”(该字符串未打印到控制台,我试图在 my_unexpected_handler 中设置断点,但没有遇到)。

我的代码有什么问题?

谢谢


抱歉,我误解了意外异常。但是,即使我将代码更改为以下

还是不行?也就是说,没有调用“my_unexpected_handler”。

0 投票
2 回答
465 浏览

c++ - C++ 异常规范 - 处理无效异常

当函数抛出不在有效异常列表中的异常时,标准行为是什么?例如,当我运行此代码时:

它在 GCC 和 Visual Studio C++ 编译器上的行为不同:

  • 在 VS 2010 上,一般异常处理程序中未捕获到预期异常。
  • 调用GCCunexpected()处理函数而不是捕获异常。

为什么会有这种差异?为什么 MS C++ 编译器不调用unexpected()回调?

0 投票
4 回答
956 浏览

java - 异常规范,有用还是没用?

第一个免责声明:这不是为了引发“语言战争”。我的报告真的需要这个(关于这个主题的澄清),我只想有有效和扎实的论据。
好的,问题来了:
在 C++ 中,异常规范已从 C++11 标准中删除,因为它被认为弊大于利。
另一方面,在 Java 中,异常规范被认为是好的和有用的东西。
这两个概念(具有异常规范的目的)在这两种语言中是否不同,这就是为什么这两个社区对它们的看法不同,或者这些概念是相似/相同的?
哪一个?异常规范是好事还是坏事?或者它在 Java 中是好的,因为(在这里我想看看一些原因)而在 C++ 中是不好的,因为(原因在这里)。
感谢任何提供建设性帮助的人。

0 投票
3 回答
432 浏览

c++ - 为什么异常规范没有用?

我已经阅读了很多关于(不)throw(X)在函数签名中使用的论点,我认为它在 ISO C++ 中指定的方式(并在当前编译器中实现)是相当没用的。但是为什么编译器不能简单地在编译时强制执行异常正确性呢?

如果我编写包含throw(A,B,C)在其签名中的函数/方法定义,编译器在确定给定函数的实现是否异常正确时应该不会有很多问题。这意味着函数体有

  • 除了;没有throw其他的throw A; throw B; throw C;
  • 没有任何函数/方法调用的 throw-signatures 限制小于throw (A,B,C);

,至少在try{}catch()捕捉其他抛出类型之外。如果编译器在不满足这些要求的情况下引发错误,则所有函数都应该是“安全的”,并且不需要运行时函数unexpected()。所有这些都将在编译时得到保证。

throw()这将要求默认指定所有非 C++ 领域代码(默认情况下extern "C"应假定它),或者如果存在一些异常互操作性,则还应指定适当的标头(至少对于 C++)throw。不这样做可以与在不同的编译单元中使用具有不同函数/方法返回类型的头文件进行比较。虽然它没有产生警告或错误,但它显然是错误的 - 由于抛出的异常是签名的一部分,它们也应该匹配。

如果我们强制执行这样的约束,它将产生三个影响:

  • 它将删除所有那些隐式try{}catch块,否则运行时检查需要,从而提高异常处理性能。
  • “异常使我们的库太大,所以我们关闭它们”的论点;会消失,因为大多数附加代码都存在于每个函数调用中那些不必要的隐式 throw/catch 指令中。如果代码被正确throw指定,大部分代码都不会被编译器添加。
  • 这会让编程界的大多数人大发雷霆,因为似乎没有人喜欢例外。现在,由于这些实际上是可用的,我们需要学习如何使用它们。

如果我们对旧代码使用一些兼容性编译器标志,它不会破坏任何东西,但是由于新的异常代码会更快,所以不使用它编写新代码是一个很好的动机。

总结一下我的问题:为什么 ISO C++ 不需要这种强制措施?有什么强有力的理由让它不存在吗?我一直认为异常只是另一个函数的返回值,但它是自动管理的,所以你可以避免编写类似的函数

加上额外的变量自动销毁和通过堆栈上的多个函数传播,所以你不需要像这样的代码

;如果你可以return只要求正确类型的功能,为什么你不能要求它throw呢?

为什么异常说明符不能更好?为什么它们不像我从一开始就描述的那样制作?

PS 我知道例外和模板可能存在一些问题——取决于这个问题的答案,也许我会问另一个问题——现在让我们忘记模板。

编辑(回应@NicolBolas):

编译器可以对异常类 X 做什么样的优化,而对 Y 却做不到呢?

相比:

和:

在这里,我包含了一些编译器不会生成汇编级别的伪代码。如您所见,知道您可以获得哪些异常可以减少代码量。如果我们在这里有一些额外的变量要销毁,额外的代码会更长。

0 投票
1 回答
3611 浏览

c++ - 关于 Hinnant 的栈分配器的问题

我一直在使用 Howard Hinnant 的堆栈分配器,它的工作原理就像一个魅力,但实现的一些细节对我来说有点不清楚。

  1. 为什么是全球运营商newdelete使用?和成员函数分别使用allocate()和。同样,成员函数使用全局放置 new。为什么不允许任何用户定义的全局或特定类的重载?deallocate()::operator new::operator deleteconstruct()
  2. 为什么对齐设置为硬编码的 16 字节而不是std::alignment_of<T>
  3. 为什么构造函数max_sizethrow()异常规范?这不是不鼓励(参见例如更有效的 C++ 第 14 条)吗?当分配器发生异常时,是否真的需要终止和中止?这会随着新的 C++11noexcept关键字而改变吗?
  4. construct()成员函数将是完美转发(到被调用的构造函数)的理想候选者。这是编写符合 C++11 的分配器的方法吗?
  5. 为了使当前代码符合 C++11,还需要进行哪些其他更改?
0 投票
2 回答
2489 浏览

c++ - 关于非抛出函数的混淆

我有 2 个关于非抛出函数的问题:

  1. 为什么要使函数不抛出?

  2. 如何使函数不抛出?如果函数内的代码实际上可能throw,那么我是否仍然应该让它不抛出?

这是一个例子:

如果里面的代码swap根本不会抛出,我还应该追加throw()吗?为什么?