有关 catch 块中 catch 语句的顺序的问题 - 编译器特定的还是语言标准?
我目前正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
根据标准,顺序是重要的。基本上,第一个与异常匹配的捕获将被捕获。
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
来自 C++ 标准 15.3/5“处理异常”:
From C++ Standard 15.3/5 "Handling an exception":
所谓的默认处理程序
catch(...)
必须是处理程序列表中的最后一个处理程序。这确实是标准所要求的。但是,此要求特定于默认处理程序。否则,标准不会限制处理程序的顺序,这意味着通常您可以创建一个处理程序来“拦截”所有异常,否则这些异常将到达列表中的其他处理程序(从而使后一个处理程序无用)。
此外,多次重复相同的 catch 子句(具有相同的类型)是完全合法的,
即使只有第一个子句有机会捕获任何内容。一个好的编译器会对类似的情况发出警告,但从形式上来说这并不是一个错误。
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 timeseven 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.