问题
I want to custom an Exception class, here's the code:
class TestException : std::exception{
public:
const char *what() const override {
return "TestException";
}
};
I used Clion and the IDE give me a warning on the function what():exception specification of overriding function is more lax than base version
But if I build the code with gcc, there's no warning came out. I used c++ 14, gcc 6.5.0
Can anybody help to explain what does the warning mean and can I just ignore it?
回答1:
what from std::exception is a virtual function and a virtual function in a derived class cannot have a laxer exception specification than the function it overrides in the base class.
This is mentioned in the section on "Exception specifications" in the standard.
18.4 Exception specifications [except.spec]
...
4. If a virtual function has a non-throwing exception specification, all declarations, including the definition, of any function that overrides that virtual function in any derived class shall have a non-throwing exception specification, unless the overriding function is defined as deleted.
And the example given (which is somewhat similar to the code in the question) illustrates this as well.
struct B
{
virtual void f() noexcept;
virtual void g();
virtual void h() noexcept = delete;
};
struct D: B
{
void f(); // ill-formed
void g() noexcept; // OK
void h() = delete; // OK
};
The declaration of
D::fis ill-formed because it has a potentially-throwing exception specification, whereasB::fhas a non-throwing exception specification.
The solution is to change your code like:
class TestException : std::exception{
public:
const char *what() const noexcept override {
return "TestException";
}
};
See compilation here.
回答2:
what member function of std::exception is declared as noexcept since C++11. You should therefore make your overridden what noexcept as well. (Actually, this is what the error message says.)
Note that the noexcept keyword must come before the override keyword (see, e.g., The order of override and noexcept in the standard for details).
回答3:
The warning you are facing is related to the fact that you are using C++14, if you would compile with C++17 this becomes an error. Hence I would not recommend ignoring it.
Whats going on?
std::exception defines the method what as: virtual const char* what() const noexcept;. You inherit from this method and you re-implement it without specifying noexcept. By result, you are telling that your implementation can throw exceptions, while the base method indicates this should never throw. (And callers will assume so)
This was fixed in C++17, which made noexcept part of the type system, and requires you to fix this code:
const char *what() const noexcept override
来源:https://stackoverflow.com/questions/53829852/exception-specification-of-overriding-function-is-more-lax-than-base-version