Search code examples
c++classexceptionthrow

c++ with and without throw() in method/constructor signature for a custom exception


I am beginner in c++, and hence apologies for this silly question. I am posting it here because I cannot find a similar answer on stackoverflow.

I was progressing through exceptions in C++ and as I was doing some hands on with custom exceptions, I have this code

class MyException: public std::exception{
public:
    virtual const char* what() const throw() {
        return "something bad happened";
    }

};

// class that throws above exception

class canGoWrong {
public:
    canGoWrong(){
        throw MyException();
    }
};

The above code was shown by the teacher. The constructor just implemented a virtual function defined in the base class exception. I got till there.

Now when I was trying a different version to practice, I tried to use a custom function instead of re-defining the virtual (as c++ doesn't strictly enforce the concept of interface, please correct me if I am wrong here.)

I wrote it as

class my_custom_shit_exception: public std::exception {
public:
    const char* show() { // I omitted the const throw() here
            return "This is an error encountered\n";
    }
};

class myclass {
public:
    myclass() {
        throw my_custom_shit_exception();
    }
};

To summarise, I didn't find a difference in behaviour in both ways

public:
const char* show() {
        return "This is an error encountered\n";
}
virtual const char* what() const throw() {
    return "something bad happened";
}
  • So why was the const throw() used in the what() virtual function? What difference it makes?

Thanks to all.


Solution

  • The function signature

    class std::exception {
        //...
    public:
        virtual const char* what() const throw();
        //...
    };
    

    can be read as: what is a virtual member function of std::exception which returns a pointer to a constant character (array) and which does not modify members of that object (hence the 2nd const) and which guarantees not to throw an exception in its code.

    Beware that the exception-specification is nowadays deprecated: Instead, since C++11 there is the noexcept specifier to declare functions that "guarantee" not to throw exceptions. Additionally, since C++17 the throw() has become a synonym for noexcept(true), but with a slightly different behaviour.

    For more details, refer to this description of noexcept.

    There it also says: "Note that a noexcept specification on a function is not a compile-time check; it is merely a method for a programmer to inform the compiler whether or not a function should throw exceptions. The compiler can use this information to enable certain optimizations on non-throwing functions [...]".