我有一个例外类如下:
#include <exception>
struct InvalidPathException : public std::exception
{
explicit InvalidPathException() {}
const char* what() const;
};
const char*
InvalidPathException::what() const {
return "Path is not valid";
}
使用-Wall -std = c ++ 0x
在GCC 4.4下编译时错误:looser throw说明符 &#39;虚拟常量字符* InvalidPathException :: what()const&#39;
错误:覆盖&#39;虚拟const char * std :: exception :: what()const throw()&#39;
非常正确,因为我覆盖了确实拥有std::exception
异常说明符的what()
throw()
方法。但通常be informed,我们不应该使用异常说明符。据我了解,它们是deprecated in C++11,但显然还没有在GCC中使用-std = c ++ 0x。
所以我现在对最好的方法感兴趣。在我开发的代码中,我确实关心性能,因此担心throw()
经常提到的开销,但实际上这个开销是如此严重?我是否正确地认为我只在实际调用what()
时遭受它,这只会在抛出这样的异常之后(同样对于从std :: exception继承的其他方法都有throw()
说明符)?
或者,有没有办法解决GCC给出的这个错误?
答案 0 :(得分:7)
空throw
规范很有用,因为它们实际上在调用者的站点上启用了编译器优化,因为Wikipedia知道(我没有方便的技术报告)。
出于优化机会的原因,在即将推出的标准中,nothrow-specifications not 已弃用,它们只是看起来不再是throw ()
,而是被称为noexcept
。嗯,是的,他们的工作方式略有不同。
Here是对noexcept
的讨论,该讨论还详细说明了为什么传统的nothrow规范在竞争对手的网站上进行了规范性的优化。
通常,您需要为每个throw
规范付费,至少使用完全兼容的编译器,GCC在这方面看起来并不总是如此。那些throw
规范必须在运行时检查,甚至是空的。这是因为如果引发的异常不符合throw
规范,则必须在该堆栈帧内进行堆栈展开(因此除了一致性检查之外还需要代码)然后{{1必须被调用。另一方面,您可能会为每个空 std::unexpected
规范节省时间/空间,因为编译器在调用该函数时可能会做出更多假设。我说,只有一个分析器可以给你一个明确的答案,你的特定代码是否受到(空!)throw
规范的影响或改进。
作为解决实际问题的方法,可以进行以下工作吗?
throws
并将其用于您的例外#define NOTHROW throw ()
和其他内容。what
时,重新定义noexcept
。 @James McNellis指出,NOTHROW
将向前兼容。在这种情况下,我建议您只使用throw ()
,除此之外,如果有疑问,请使用个人资料。