What is the difference between std::runtime_error
and std::exception
? What is the appropriate use for each? Why are they different in the first place?
2 Answers
std::exception
is the class whose only purpose is to serve as the base class in the exception hierarchy. It has no other uses. In other words, conceptually it is an abstract class (even though it is not defined as abstract class in C++ meaning of the term).
std::runtime_error
is a more specialized class, descending from std::exception
, intended to be thrown in case of various runtime errors. It has a dual purpose. It can be thrown by itself, or it can serve as a base class to various even more specialized types of runtime error exceptions, such as std::range_error
, std::overflow_error
etc. You can define your own exception classes descending from std::runtime_error
, as well as you can define your own exception classes descending from std::exception
.
Just like std::runtime_error
, standard library contains std::logic_error
, also descending from std::exception
.
The point of having this hierarchy is to give user the opportunity to use the full power of C++ exception handling mechanism. Since 'catch' clause can catch polymorphic exceptions, the user can write 'catch' clauses that can catch exception types from a specific subtree of the exception hierarchy. For example, catch (std::runtime_error& e)
will catch all exceptions from std::runtime_error
subtree, letting all others to pass through (and fly further up the call stack).
P.S. Designing a useful exception class hierarchy (that would let you catch only the exception types you are interested in at each point of your code) is a non-trivial task. What you see in standard C++ library is one possible approach, offered to you by the authors of the language. As you see, they decided to split all exception types into "runtime errors" and "logic errors" and let you proceed from there with your own exception types. There are, of course, alternative ways to structure that hierarchy, which might be more appropriate in your design.
Update: Portability Linux vs Windows
As Loki Astari and unixman83 noted in their answer and comments below, the constructor of the exception
class does not take any arguments according to C++ standard. Microsoft C++ has a constructor taking arguments in the exception
class, but this is not standard. The runtime_error
class has a constructor taking arguments (char*
) on both platforms, Windows and Linux. To be portable, better use runtime_error
.
(And remember, just because a specification of your project says your code does not have to run on Linux, it does not mean it does never have to run on Linux.)

- 13,850
- 9
- 56
- 64

- 312,472
- 42
- 525
- 765
-
1thank you. great answer. though i wonder if there is ever a need to have different type of exception...just a thought though. – sivabudh Oct 15 '09 at 03:41
-
1If there is a potability that the exception can be re-covered from, then a different type of exception can be useful as we can use the exception handling mechanism to direct the exception to handler that will try and correct the problem. If there is no chance of recovery than one of the standard exceptions is fine. – Martin York Oct 15 '09 at 03:48
-
2Just as an aside: there is no rule, anywhere, that forces you to derive from `std::exception`. Sure, all `std` things throw derived classes of that, but there is absolutely no reason to only throw `std::exception` derived objects. – rubenvb Nov 07 '14 at 14:18
-
1@rubenvb I did not know about that, but I think it will clearify the code for future maintenance if only objects of classes derived from exception are thrown. Example: I like to find out what custom exceptions are implemented in my code base and search for classes derived from exception. – this.myself Nov 07 '14 at 15:19
std::exception
should be considered (note the considered) the abstract base of the standard exception hierarchy. This is because there is no mechanism to pass in a specific message (to do this you must derive and specialize what()
). There is nothing to stop you from using std::exception and for simple applications it may be all you need.
std::runtime_error
on the other hand has valid constructors that accept a string as a message. When what()
is called a const char pointer is returned that points at a C string that has the same string as was passed into the constructor.
try
{
if (badThingHappened)
{
throw std::runtime_error("Something Bad happened here");
}
}
catch(std::exception const& e)
{
std::cout << "Exception: " << e.what() << "\n";
}

- 7,709
- 6
- 64
- 90

- 257,169
- 86
- 333
- 562
-
1Thanks for the answer martin. However, i use std::exception() the same way as you described above. i.e. std::exception() constructor can also take a std::string() or const char*. – sivabudh Oct 16 '09 at 01:04
-
16Not according to the standard. std::exception has one constructor that takes no arguments. Using a version that accepts a std::string or a C-String is non portable. – Martin York Oct 16 '09 at 17:30
-
12Because of Microsoft, I got used to throwing `std::exception(std::string)`. Now I realize that I must throw `std::runtime_error` if I want my code to work in Linux (GCC). – unixman83 Dec 28 '11 at 09:43