Objection to Exceptions

One of my friends raised this issue for me. I am stuck because I do not know how to use exceptions. Keep in mind that we both work in a production environment where we use C ++, but we do error handling in the C tradition. His problem was something like this:

Function A calls B , which in turn calls C An exception is thrown from C , and the catch block for this exception is in A What happens to resources received in B before calling C ? How do we clean them? My answer was to use RAII. But even when I said this, I knew that it would not work. We have huge code bases written in C mode. Nowhere in the code have I seen automatic pointers, etc. Resources do not necessarily end in classes. Even when they are, destructors are left to the compiler in most cases. In short, everything is done manually.

The real problem is what to do to move from handling C errors to exceptions with the weight of a huge code base? The problem my friend asked is just one of the possible questions that can be raised when you have legs based on C error handling and you want to know how the transition from there to exceptions can happen.

+8
c ++ exception error-handling
source share
7 answers

There is a technique developed by Andrei Alexandrescu and Joshua Lehrer called Scope Guard , which provides a technique for providing a sphere-exit code as soon as you select an object and open an area for it at that point.

The programming language D actually has it as a standard.

In acceleration libraries

There is an extension of this Scope Exit . If your code is not safe for exceptions, since function B is not displayed, it will not be processed properly if something changes.

Destructors will execute when unwinding the call stack after an exception. That is why you must make sure that they themselves do not throw any exceptions.

+5
source share

The real problem is what to do to move from handling C errors to exceptions with the weight of a huge code base?

No, the real problem is that since you are programming in C ++, you should have done this for a long time. Even if your own code does not throw exceptions, some code in the standard library and runtime system may throw ( new , dynamic_cast ) and, of course, any third-party software that you use may throw well.

I agree that Scope Guard is probably the best way to add exception-security as an afterthought. However, do not be fooled into thinking that you do not need to do this until you yourself throw the exception. You use the language with exceptions , so you better start communicating with them as soon as possible.

+2
source share

You still have to migrate to RAII because you cannot make mistakes with it when changing the control flow, among other things. You need to upgrade. Exceptions mean that you cannot completely update any function that might have an exception in it.

+1
source share

C ++ Does not finally support last-minute material management at the end of a block.

What happens when function C throws an exception, it returns from the function. This means that all local variables will be destroyed.
Then the program will return to the code in B , it will check the catch lock, see what is not, and return to the function A. Again, all the local variables in B will be freed.

You must remember that you are working in C ++ ... you must manage your objects. Therefore, if you have objects that are simply interested in freely in B (with pointers or something else), then this is a bad code design and they will not be released.

If you know in B that there may be an exception in C , you can just put catch there and then throw the exception.

Closest you can get to the finally block with catch(...) and use it to free memory ... but it will only be introduced if there really was an exception, so it is not identical to finally

 try { } catch(...) { // free stuff affected by an exception here } 

If you want to work just like a finally block, you can do:

 try { //Do stuff goto finally } catch(...) { finally: // free stuff affected by an exception here } 

For all of you that have a problem with goto ..., it is still a command, and this is a great example that no break or continue or some built-in function can replace goto .

A little bit about go

+1
source share

Your friend is right, and this is one of the reasons Google doesn't use exceptions internally. For an explanation of the problem, see http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Exceptions (and open the small arrow).

0
source share

Excerpt from my abandoned homepage ...

Without repeating in detail all the problems inherent in the exception (1) I want to mention only the Main idea: the difficult part is not where the exception is thrown (throw) or where the exception (catch), but in the methods all classes are eliminated almost asynchronously during the process of expanding the stack.

Pay attention to how the methods are written. It is relatively easy to avoid loss of resources in case of exceptions (using auto_ptr and similar classes), but things are much more complicated when one takes into account the logical state of an object or other objects to be manipulated before throwing. in the strictest sense of a safe exception, the method must either succeed or be non-op: in other words, the logical state of the object called (and other involved objects) should be the same if the exception is raised: no difference should be visible through the common interface of all participants classes.

...

(1) For a detailed description, read the article “Handling Exceptions: False Sense of Security” by Tom Cargill, available online or an interesting collection of problems / solutions that this article created on USENET is available in Herb Sutter’s book Exceptional C ++ ISBN 0-201- 61562-2 =.

0
source share

Rejoice that you have exceptions. Consider what happens with the error return codes in your example. Function C returns an error code. B , being naive as he is, swallows him. Caller A , which could handle it, did not even report an error.

It is best to go from C directly to C ++ 0x. It offers a new feature, lambda. These are anonymous functions defined in other functions. You can put your C cleanup code and call it using the scopeguard object. Example (I missed a macro)

0
source share

All Articles