Monday, November 29, 2010

And what’s the point?

This note is about C++ exceptions.

The scenario I mention here is not unique. Actually it is one of the many other similar situations I have encountered in which C++ exception mechanism is of no use.

I begin with an Integrated Development Environment (IDE), written in C++. User loads an application in a language supported by the IDE. The IDE loads a dynamic library to execute user’s application. This is the general idea.

Suppose, during a debug session user code causes a segmentation fault on a UNIX platform. An obvious course of action is to inform the user that his program crashed, then return control to the IDE. User can then set break points and find the location of crash, and so on.

What happens of course is that the entire IDE crashes. C++ can only catch exceptions thrown in a program. However, it is not possible to define a C++ exception to match up with segmentation fault, because it is not possible to sense the fault prior to its happening.

Well, you try UNIX signal handling. This takes a while trying different approaches. For instance you attempt to throw an exception from inside the handler, you try to get a trace of the stack at the time of crash hoping that you can return to a reasonable point in your program, etc. Nothing works, of course.

Suddenly you find out that in C++ you can redefine the terminate() function. After a while you realize that the redefinition only allows you to change its message to something like, “Hi there, I am in terminate function!”. And now you are thinking, what is the whole point behind this design?

Basically, once a signal handler is invoked by UNIX operating system the C++ context is lost. There is nothing that can be done, neither in C++, nor even with the help of UNIX facilities. What is needed is a runtime library that could do the clean up by calling destructors on objects created in a try block, and bring control back to the catch block. But C++ can only do that for exceptions thrown in your program. The latter is the work of the compiler, not the runtime library.

The point to keep in mind is that C++ is merely a front-end parser to the C compiler. The runtime libraries are those of C language. Simply put, C++ is an extension of the C parser not to be confused with an extension of the C language. That means, any attempt for materializing a particular feature for C++ that cannot be supported by C runtime library will result in a lot of wasted time. After all, there is only so much that C++ parser can do in telling C what to do. In particular, we do not want to change the behavior of C in order to accommodate for another language.