exception specification of overriding function is more lax than base version

三世轮回 提交于 2020-02-23 09:14:40

问题


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::f is ill-formed because it has a potentially-throwing exception specification, whereas B::f has 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!