有关 catch 块中 catch 语句的顺序的问题 - 编译器特定的还是语言标准?

发布于 2024-08-24 21:44:47 字数 481 浏览 6 评论 0原文

我目前正在使用 Visual Studio Express C++ 2008,并且对 catch 块排序有一些疑问。不幸的是,我在网上找不到答案,所以我向专家提出这些问题。

我注意到,除非将 catch (...) 放置在 catch 块的末尾,否则编译将失败并出现错误 C2311。例如,以下内容将编译:

catch (MyException)
{
}
catch (...)
{
}

而以下内容则不会

catch (...)
{
}
catch (MyException)
{
}

:请问这是C++语言标准中定义的,还是只是微软编译器比较严格?

b. C# 和 Java 也有相同的规则吗?

c.顺便说一句,我还尝试创建一个基类和一个派生类,并将基类的 catch 语句放在派生类的 catch 语句之前。这编译没有问题。难道没有语言标准来防止这种做法吗?

I am currently using Visual Studio Express C++ 2008, and have some questions about catch block ordering. Unfortunately, I could not find the answer on the internet so I am posing these questions to the experts.

I notice that unless catch (...) is placed at the end of a catch block, the compilation will fail with error C2311. For example, the following would compile:

catch (MyException)
{
}
catch (...)
{
}

while the following would not:

catch (...)
{
}
catch (MyException)
{
}

a. Could I ask if this is defined in the C++ language standard, or if this is just the Microsoft compiler being strict?

b. Do C# and Java have the same rules as well?

c. As an aside, I have also tried making a base class and a derived class, and putting the catch statement for the base class before the catch statement for the derived class. This compiled without problems. Are there no language standards guarding against such practice please?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

写给空气的情书 2024-08-31 21:44:47

根据标准,顺序是重要的。基本上,第一个与异常匹配的捕获将被捕获。

a) 因为 catch(...) 会使任何后续的 catch 变得无关紧要,所以标准只允许它成为最后一个 catch。

b) C# 和 Java 有类似的规则。

c) 在派生类之前捕获(通过引用或指针)基类将使派生类的代码变得无关紧要。然而,该标准确实允许这样做

According to the standard, the order is significant. Basically the first catch that matches the exception will be caught.

a) Because catch(...) will make any following catches irrelevant, the standard only allows it to be the last catch.

b) C# and Java have similar rules.

c) catch (by reference or pointer) of a base before a derived class will make the code for the derived irrelevant. However, the standard does allow this

汹涌人海 2024-08-31 21:44:47

来自 C++ 标准 15.3/5“处理异常”:

try 块的处理程序按照出现的顺序进行尝试。这使得编写永远无法执行的处理程序成为可能,例如通过将派生类的处理程序放置在相应基类的处理程序之后。

处理程序的异常声明函数中的 ... 与函数参数声明中的 ... 类似;它指定任何异常的匹配。如果存在,... 处理程序应是其 try 块的最后一个处理程序。

From C++ Standard 15.3/5 "Handling an exception":

The handlers for a try block are tried in order of appearance. That makes it possible to write handlers that can never be executed, for example by placing a handler for a derived class after a handler for a corresponding base class.

A ... in a handler’s exception-declaration functions similarly to ... in a function parameter declaration; it specifies a match for any exception. If present, a ... handler shall be the last handler for its try block.

蓬勃野心 2024-08-31 21:44:47

所谓的默认处理程序 catch(...) 必须是处理程序列表中的最后一个处理程序。这确实是标准所要求的。但是,此要求特定于默认处理程序。

否则,标准不会限制处理程序的顺序,这意味着通常您可以创建一个处理程序来“拦截”所有异常,否则这些异常将到达列表中的其他处理程序(从而使后一个处理程序无用)。

此外,多次重复相同的 catch 子句(具有相同的类型)是完全合法的,

catch (int) {
  // ...
}
catch (int) {
  // ...
}

即使只有第一个子句有机会捕获任何内容。一个好的编译器会对类似的情况发出警告,但从形式上来说这并不是一个错误。

The so called default handler catch(...) must be the last handler in the list of handlers. This is indeed required by the standard. However, this requirement is specific to default handler.

Otherwise the standard does not restrict the ordering of the handlers, meaning that generally you can create a handler that would "intercept" all exceptions that would otherwise reach some other handler down the list (thus making the latter handler useless).

Moreover, it is perfectly legal to repeat the same catch clause (with the same type) several times

catch (int) {
  // ...
}
catch (int) {
  // ...
}

even though only the first one will have a chance of ever catching anything. A good compiler will issue a warning for cases like that, but formally it is not an error.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文