Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are exceptions?

We talk about exception handling everyday. We all konw that it is something that is created when execution meet some unexpected situation.

Here come several questions:

  • What is an exception? What's its most low-level in-memory composition? In .NET, I can think of it as some object instance of some exception type. In the native world, what is it made of? Some data sturcures?

  • Who create the exception if the exception is not thrown explicitly by the programmer as the following code shows? Is it part of the support that certain language runtime provides?

    SomeException e = new SomeException(); throw e;

  • What is the exception working paradigm? Is it true that when some error happens, an instnace of the corresponding data structure/type is created by the language runtime to represent the details of the error?

  • How could we know all the possible unexpected situations at runtime and thus create enough exception data structures/types to represent them?

Thanks for your replies.

like image 754
smwikipedia Avatar asked Dec 06 '22 01:12

smwikipedia


2 Answers

The answers to your questions depend a lot on what language we're talking about.

C doesn't have exceptions at all, although there are proprietary language extensions.
C++ has a way to "throw" an arbitrary object at any point in your code and "catch" it somewhere higher up the call stack.
C# has a way to "throw" objects derived from System.Exception and also "catch" those from higher up the stack. Additionally, I think the .NET runtime reports some issues per throwing an exception itself.

  • What is an exception? What's its most low-level in-memory composition? In .NET, I can think of it as some object instance of some exception type. In the native world, what is it made of? Some data sturcures?

In C++, it's simply an arbitrary object, that was created like other objects in code:

throw 42;                     // throws an int object
throw "blah";                 // throws a char[5] object
throw std::string("arg!");    // throws a std::string object
throw my_type(42);            // throws a my_type object
throw std::exception("doh!"); // throws a std::exception object

The matching of thrown exceptions to catch phrases is pretty similar to the matching of overloaded functions. (A big difference is that catch phrases are ordered. That is, the first to match at all will "win" and catch the object. Overloaded functions, however, must always provide an unambiguously best match.)

  • Who create the exception if the exception is not thrown explicitly by the programmer as the following code shows? Is it part of the support that certain language runtime provides?

In C++, exceptions can almost only be thrown from code. It could be your own code, someone else's code, some library's code, or the standard library's code. But there will usually have to be a throw statement somewhere. There are a few exceptions (no pun intended) to this, like std::bad_alloc thrown by new (which is likely thrown from a throw statement in code, but I think doesn't have to) and std::bad_cast, thrown from dynamic_cast<>. (Also, the next standard, C++1x, expected next year, allows exceptions to somehow cross thread borders, which probably requires standard library implementors to find a way to store an exception in one thread and rethrow it from another. But I'm pretty hazy on this.)

    SomeException e = new SomeException(); throw e;

In C++ you can, but you rarely ever would want to, throw pointers. You either do

SomeException e; throw e;

or

throw SomeException();
  • What is the exception working paradigm? Is it true that when some error happens, an instnace of the corresponding data structure/type is created by the language runtime to represent the details of the error?

There area few places where the C++ standard library throws exceptions, but other than that I can only think of the two features mentioned above (plus the one in C++1x) where the runtime throws exceptions "itself".

  • How could we know all the possible unexpected situations at runtime and thus create enough exception data structures/types to represent them?

It's common to only throw objects of classes derived from std::exception in C++, although I have come across code that used their own exception class hierarchy which wasn't rooted in std::exception. The problem with the exception hierarchy in the standard library is that its classes derives non-virtually from each other, which makes it impossible to have your own exception hierarchy shadowing the one from the standard library using multiple inheritance. (Like having your own OutOfRange exception type that inherits from std::out_of_range and from your exception base class MyException, which inherits from std::exception.)

The C++ way to deal with exceptions is mainly based on the following principles:

  • Write your code in ways that makes it immune to exceptions thrown at any point. Use RAII and other techniques to achieve that.
  • Catch exceptions only at places where you can do something about them.
  • Throw exceptions only in exceptionally circumstances. Do not use them for control flow. (C++ exceptions were designed with the goal for vendors to be able to implement them so that the overhead is minimized in the non-exceptional case, at the cost of the exceptional case.)
like image 179
sbi Avatar answered Dec 11 '22 03:12

sbi


At its root an exception is a special situation with a predefined handling mechanism. All the rest is up to the implementation.

The type is there because it's convenient to have an object storing extra data on the kind of the special situation. That said an exception could be a controlled switch that would for example just restart a machine each time the hardware can't perform the operation.

like image 24
sharptooth Avatar answered Dec 11 '22 03:12

sharptooth