0

Doing a project, I'm trying to create a HandleError header with a bunch of classes. Inside of my class BadNumber, I have a public method/function that takes in as a string type and num. However, when I'm trying to test it, I get an error asking for exception specification of overriding function is more lax than base version because I'm inheriting it from public std::exception. I Googled around how to fix this and it is recommending me to do a noexcept override call in my what() for this exception call (link here). The example is almost identical to mine with the same error message.

Code (compiling with GCC/Clang c++11):

#include <exception>
#include <string>

class BadNumber : public std::exception
{
    private:
        std::string _msg;
    public:
        BadNumber(std::string type, std::string num) : _msg(num + "is invalid type for " + type) {}
        const char *what() const noexcept override
        {
            return (_msg.c_str());
        }
};

Error message:

src/../inc/HandleError.hpp:23:15: error: exception specification of overriding function is more lax than base version
                const char *what() const noexcept override
                            ^
/Library/Developer/CommandLineTools/usr/include/c++/v1/exception:102:25: note: overridden virtual function is here
    virtual const char* what() const _NOEXCEPT;

I did what it was asked and did some research, but still no luck and still doing more. Your help is much appreciated and it will be always helpful to get some feedback and constructive as possible. Thank you for your time and patience :)

Community
  • 1
  • 1
Zeid Tisnes
  • 396
  • 5
  • 22
  • 3
    Can you let us know what the `_NOEXCEPT` macro evaluates to? Also, what compiler are you using? – Adrian Mole Jan 26 '20 at 14:46
  • Sure, it is compiling with `c++11` and the `_NOEXCEPT` is: `/Library/Developer/CommandLineTools/usr/include/c++/v1/exception:102:25: note: overridden virtual function is here virtual const char* what() const _NOEXCEPT;` I will also add it to the original post to make it more clear – Zeid Tisnes Jan 26 '20 at 14:51
  • 2
    Not what I meant! c++11 is the standard - what tool are you using (GCC?). And I don't have the header file you indicate, so *please* look for the definition of `_NOEXCEPT` and show us what it is. – Adrian Mole Jan 26 '20 at 14:55
  • My bad, it is compiled with GCC and evaluated from the `exception` header. – Zeid Tisnes Jan 26 '20 at 14:58
  • As for the value of `_NOEXCEPT`, it is quite ambiguous for me. I'm a beginner in C++ by the way, but this is what I found about the macro itself https://stackoverflow.com/a/33840306/6017248 – Zeid Tisnes Jan 26 '20 at 15:00
  • 2
    What if you replace `noexcept` with `_NOEXCEPT` in your override? If that compiles, you need to dig into what this macro is defined at. For that, `#define` it at the top (before you `#include` anything) to some random value. You'll then get a warning/error at the place of the original definition. – Ulrich Eckhardt Jan 26 '20 at 15:01
  • 1
    OK, we're half way there! On my system (MSVC and/or Clang), there is no use nor definition of `_NOEXCEPT` in the `exception` header, which is why I want to know **what it is defined as on your system**. Try right-clicking on it and going for 'find definition', or some such. – Adrian Mole Jan 26 '20 at 15:01
  • So it was fun using the "find/go definition" in my Visual Studios. It shows me that it has a `#define _LIBCPP_EXCEPTION` running it on a MacOS @AdrianMole – Zeid Tisnes Jan 26 '20 at 15:12
  • No much happens by replacing it. Instead, it creates a warning and error message saying `src/../inc/HandleError.hpp:24:38: warning: 'override' keyword is a C++11 extension [-Wc++11-extensions] const char *what() const _NOEXCEPT override ^ src/../inc/HandleError.hpp:18:7: error: exception specification of overriding function is more lax than base version class BadNumber : public std::exception`. Still trying to wrap around my head and making more confusing afterwards @ulrich-eckhardt. – Zeid Tisnes Jan 26 '20 at 15:15
  • are you sure you are using gcc? The version of gcc shipped with the macos developer tools doesn't support c++11 – Alan Birtles Jan 26 '20 at 15:31
  • Oh I get it. I'm using clang++ (and I think g++ also works almost the same). Fixed it now – Zeid Tisnes Jan 26 '20 at 15:37
  • Sorry, but please reread your question and fix everything that isn't true or missing. For example, it still says "GCC/Clang", so which is it now? Also, you mention C++11, but that error message from the above comment indicates it uses an earlier standard. Which compiler and version do you use? What commandline do you use to compile the code? What is the actual code? Note that the error message in your question doesn't match the code, because it mentions line numbers that don't exist. I'm voting to close this question for now, there's too much broken here. – Ulrich Eckhardt Jan 26 '20 at 22:19

1 Answers1

0

So I realized that I must have each class as a virtual destructor because otherwise, I would use the base destructor which I don't want to do that. This is my solution:

class BadNumber : public std::exception
{
    private:
        std::string _msg;
    public:
        virtual ~BadNumber() throw() {return ;}
        BadNumber(std::string type, std::string num) : _msg(num + "is invalid type for " + type) {}
        virtual const char *what() const throw()
        {
            return (_msg.c_str());
        }
};
Zeid Tisnes
  • 396
  • 5
  • 22
  • This doesn't make sense: The `std::exception` destructor is already `virtual` and `public`. Overriding it with an empty destructor will not change this. BTW: Consider using `std::domain_error` instead of writing your own. – Ulrich Eckhardt Jan 26 '20 at 22:13