Search code examples
c++c++11exceptionnoexcept

what is std::exception::what() and why to use it?


I came from c++98, and i am trying to make my way in to c++11 and so on. i came across the public member function , std::exception::what, <=> virtual const char* what() const noexcept;

from this example givin in c++ reference : what_example, i can understand the usage but i have a few questions:

// exception::what
#include <iostream>       // std::cout
#include <exception>      // std::exception

struct ooops : std::exception {
  const char* what() const noexcept {return "Ooops!\n";}
};

int main () {
  try {
      throw ooops();
  } catch (std::exception& ex) {
      std::cout << ex.what();
  }
  return 0;
}
  1. in c++98 the what() was : virtual const char* what() const throw();, and in c++11, it becomes virtual const char* what() const noexcept;. what is the noexcept at the end? did it bring something new?
  2. why should i use what() it at all? i can emplement my own tostring method in my class exception and call it instead!
  3. in the return value of what(), see below, guaranteed to be valid at least until...or until a non-const member function of the exception object is called. what is the meaning of or until a non-const member function of the exception object is called, could some one explain with example and why is that ?

what() return value

A pointer to a c-string with content related to the exception. This is guaranteed to be valid at least until the exception object from which it is obtained is destroyed or until a non-const member function of the exception object is called.

thanks.


Solution

    1. what is the noexcept at the end?

    It is a new specifier introduced in C++11. In very short, it means that the function will not throw an exception. noexcept has same meaning as throw().

    did it bring something new?

    noexcept is an improvement over the old throw specifier, which has since been deprecated (C++11) and then removed (C++20) from the language. It accepts a boolean expression that determines whether the function is noexcept or potentially throwing. This is useful in generic template programming because some instances of a template may be potentially throwing while others might not be.

    1. why should i use what() it at all? i can emplement my own tostring method in my class exception and call it instead!

    Because you may be using functions that are not written by you, and therefore will not throw your exception class. For example, some standard functions will in some cases throw an exception, and all standard exceptions derive from std::exception. In such case, the only way to access the error message is through the what member function.

    Same applies when other people call your function. They might not want to / or need to know about your special exception class, but they can still catch it and print the message if you inherit std::exception.

    1. what is the meaning of or until a non-const member function of the exception object is called

    The meaning is literal. If you call what on an exception object derived from std::exception, and store the returned pointer, and then call a non-const member function of that exception object then the stored pointer will be invalid.

    Any attempt to indirect through an invalid pointer such as attempting to print the exception message will result in undefined behaviour.