bel*_*daz 9 c++ gcc exception-specification c++11
我有一个异常类如下:
#include <exception>
struct InvalidPathException : public std::exception
{
explicit InvalidPathException() {}
const char* what() const;
};
const char*
InvalidPathException::what() const {
return "Path is not valid";
}
Run Code Online (Sandbox Code Playgroud)
使用-Wall -std = c ++ 0x在GCC 4.4下编译时
错误:对'virtual const char*的错误抛出说明符*InvalidPathException :: what()const'
错误:覆盖'virtual const char*std :: exception :: what()const throw()'
完全正确,也因为我重写std::exception的what()是确实有一个方法throw()异常说明.但是,通常会通知我们,我们不应该使用异常说明符.据我所知,它们在C++ 11中已被弃用,但显然还没有在GCC中使用-std = c ++ 0x.
所以我现在对最好的方法感兴趣.在我正在开发的代码中,我确实关心性能,所以担心经常提到的开销throw(),但实际上这个开销是如此严重?我是否正确地认为我只会在what()实际调用时遇到它,这只会在抛出这样的异常之后(同样对于从std :: exception继承的其他方法都有throw()说明符)?
或者,有没有办法解决GCC给出的这个错误?
空throw规范是有用的,因为它们实际上在调用者的站点上启用了编译器优化,正如维基百科知道的那样(我没有技术报价方便).
并且出于优化机会的原因,nothrow-specifications 在即将推出的标准中不会被弃用,它们看起来不再像以前那样throw ()被称为noexcept.嗯,是的,他们的工作方式略有不同.
以下是noexcept对此的讨论,也详细说明了为什么传统的nothrow规范在竞争对手的网站上进行了优势的优化.
Generally, you pay for every throw specification you have, at least with a fully compliant compiler, which GCC has, in this respect, appearantly not always been. Those throw specifications have to be checked at run-time, even empty ones. That is because if an exception is raised that does not conform to the throw specification, stack unwinding has to take place within that stack frame (so you need code for that in addition to the conformance check) and then std::unexpected has to be called. On the other hand, you potentially save time/space for every empty throw specification as the compiler may make more assumptions when calling that function. I chicken out by saying only a profiler can give you the definitive answer of whether your particular code suffers from or improves by (empty!) throws specification.
As a workaround to your actual problem, may the following work?
#define NOTHROW throw () and use it for your exception's what and other stuff.noexcept, redefine NOTHROW.As @James McNellis notes, throw () will be forward-compatible. In that case, I suggest just using throw () where you have to and, apart from that, if in doubt, profile.