我有一个异常类如下:
#include <exception>
struct InvalidPathException : public std::exception
{
explicit InvalidPathException() {}
const char* what() const;
};
const char*
InvalidPathException::what() const {
return "Path is not valid";
}
在 GCC 4.4 下使用 -Wall -std=c++0x 进行编译时
错误:更宽松的抛出说明符
'虚拟常量字符*
InvalidPathException::what() const'
错误:覆盖“虚拟常量字符*”
std::exception::what() const throw ()'
也很正确,因为我凌驾于一切之上std::exception
's what()
确实有一个方法throw()
异常说明符。但正如人们经常会被告知 http://www.gotw.ca/publications/mill22.htm,我们不应该使用异常说明符。据我了解,他们是在 C++11 中已弃用 http://en.wikipedia.org/wiki/C%2B%2B0x#cite_ref-sutter0310_6-1,但在 GCC 中显然还没有 -std=c++0x。
所以我现在对最好的方法感兴趣。在我正在开发的代码中,我确实关心性能,因此担心经常提到的开销throw()
,但实际上这个开销有这么严重吗?我是否正确地认为我只会在以下情况下遭受痛苦what()
实际上被调用,只有在抛出这样的异常之后才会被调用(对于从 std::exception 继承的其他方法也同样如此,所有方法都有throw()
说明符)?
或者,有没有办法解决 GCC 给出的这个错误?
Empty throw
规范很有用,因为它们实际上可以在调用者的站点上启用编译器优化,如维基百科 http://en.wikipedia.org/wiki/Exception_handling#Checked_exceptions知道(我手头没有技术报价)。
出于优化机会的原因,无抛出规格not在即将推出的标准中已弃用,它们只是看起来不像throw ()
不再有,但被称为noexcept
。嗯,是的,而且它们的工作方式略有不同。
是关于的讨论noexcept
它还详细说明了为什么传统的无抛出规范禁止在被调用方站点进行优化。
一般来说,您为每个throw
规范,至少使用完全兼容的编译器,而 GCC 在这方面似乎并不总是如此。那些throw
必须在运行时检查规范,即使是空规范。这是因为如果引发了不符合规定的异常throw
规范,堆栈展开必须在该堆栈框架内进行(因此除了一致性检查之外,您还需要代码),然后std::unexpected
必须被调用。另一方面,您可能会为每个人节省时间/空间empty throw
规范,因为编译器在调用该函数时可能会做出更多假设。我胆怯地说,只有分析器才能给您明确的答案,即您的特定代码是否受到以下影响或得到改善(empty!) throws
规格。
作为解决您的实际问题的方法,以下方法可以吗?
- 介绍
#define NOTHROW throw ()
并将其用于您的例外what
和其他东西。
- 当海湾合作委员会实施
noexcept
, 重新定义NOTHROW
.
Update
正如@James McNellis 所说,throw ()
将向前兼容。在这种情况下,我建议只使用throw ()
除此之外,如果有疑问,请进行配置文件。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)