The first version of this article was actually written in late 1995, and appeared in The C++ Report in March 1996. At the time it was written, the C++ Standardization committee had released the first Committee Draft of the Standard. This froze the feature set of the language and the libraries, but ultimately much work remained to be done on the details. The second Committee Draft of the C++ Standard was released to the public in December 1996. The Final Draft was approved in November 1997, though it was May 1998 before it was released by ISO to the public (two days ago actually).
In the first Committee Draft, Chapter 15 - Exception Handling was 7 pages long. By the second Committee Draft it had grown to 9 pages; still one of the shortest chapters in the entire Standard. As I noted in the first version of this article, if one were to judge the complexity of using exceptions solely on the number of sentences needed to specify their behavior in the language, it would be easy to conclude that exceptions were one of the easier aspects of C++ to master.
When I started to use exceptions, it rapidly became apparent that exceptions are much more difficult to use effectively than it first appears. In fact, the more I explored how exceptions can interact with non-exception handling code, the more convinced I became that exceptions may be the most difficult feature of C++ to use. The original version of this article discussed the problems with using exceptions and presented 8 general guidelines (now increased to 10) and a number of specific tactics for coping with those problems. In the intervening two years, I feel that the original article has held up very well. What has changed however, is some of the terminology in use in the C++ community, and in the C++ Standard itself.
The original 1995 Committee Draft was completely silent on the concept of "exception safety" in the Standard Library. A number of members of the committee felt that this was unacceptable. Around the time of the second Committee Draft, a couple of different proposals were put forth to correct this situation. The Final Draft Standard therefore now has some general requirements on how certain Standard Library functions must cope with exceptions. While the basic principals in the Final Draft Standard correspond very closely with a couple of the guidelines in the original article, the Standard uses different terminology. Given that the arrival of Standard C++ finally seems imminent, it seemed reasonable to revise the original article to at least include a mention or two of what the Standard itself actually says.
i. In order to be effective, exception handling must pervade the entire application -- it can not be localized to a function or even a class.
ii. Exceptions are almost like asynchronous events -- they do not respect semi-colons and can appear from the middle of an expression.
an exception will propagate up the call stack, eventually aborting the entire program.
It is the first of these that is the real problem. When using other features of C++ such as classes, overloaded operators, virtual functions, or templates, it may be difficult to write the code correctly in the first place, but once written it is easy to use from then on. Exceptions go against this trend. Throwing an exception is easy; writing the code that uses the function that throws the exception is the hard part. Every function that can have an exception propagate out of it must be designed to propagate that exception correctly. As Tom Cargill says in  "The really hard part of using exceptions is to write all the intervening code in such a way that an arbitrary exception can propagate from its throw site to its handler, arriving safely and without damaging other parts of the program along the way."
is a typical C idiom that has been carried over (with some major extensions) into C++. In fact, one can almost say that the Standard Template Library was designed around such idioms. In C++, i and j can be two different, user-defined iterator types. For such types, both the post-increment operator (++), and the de-reference operator (*) represent user defined function calls. Assume that i iterates over a container of A objects (and *i returns an A&), and j iterates over a container of B objects (and *j returns a B&). Assignment will have been overridden if A is a user defined type, but it may not be defined specifically for the type represented by B, necessitating invocation of some user-defined conversion function. Another user-defined conversion function may have to be invoked to convert the result of the assignment statement (presumably an A&, but potentially anything) into something that can be converted to type bool for the "while" condition. Any of these user defined operators or conversions might throw an exception -- or any of the functions that they invoke, and so on. If an exception occurs in this statement, the user may have no idea where it came from. More importantly, the order of evaluation of several parts of the above expression is unspecified. Therefore, if an exception appears, the user may have a hard time determining the current state of i, or j or *i.
Finally, as noted in (iii), exceptions can not be ignored. With older error reporting techniques, nothing but discipline forced the programmer to check the return value or error code. Even if you knew errors were possible, you did not have to check the return value immediately, just as long as it was checked before it mattered. With exceptions, this is no longer possible. You have to cope with an exception when and where it occurs, not when and where it is convenient for you. This is true even if you do not plan to actually handle the exception.
• Set an internal error flag. An operator! function or a conversion to bool or void* is often provided to simplify testing the state of the object. Such a scheme can be used to tell if a constructor (or an operator) succeeded or failed, but it does not tell anything about why the failure occurred. For that, a member function that returns the value of an error code is usually provided.
• Two-stage construction. In this scheme, the actual object constructor only initializes memory. A second "initialization" function is called after an object is 'constructed' to do resource allocation and any other complex operations that might encounter errors. This scheme does provide a means to return error indications to the user, but the user has to know about the need to initialize the object before it can be used. It does not work with overload operators.
Since there is no standardization for any of this, it is difficult to combine libraries that use slightly different techniques. It also is virtually impossible to use such classes to instantiate general purpose templates like those that are now part of the Standard C++ Library. The truth is: without exceptions, a lot of the features that make C++ so powerful -- constructors, overloaded operators, and templates -- are either not as robust as we need them to be, or simply can not be used in situations where good error handling is required.
What follows are some guidelines that I have put together on how to cope with exceptions (typically these days this topic is given the broad general title of "exception safety"). These guidelines are general, high level concepts. Complying with a guideline may involve re-writing a function or major changes to a class library. After each guideline, I present more specific tactics which might be used in certain circumstances to satisfy a guideline. As with most such offerings, every user will have to evaluate their own circumstances and determine which of these guidelines and tactics are applicable to their situation. I must admit that I have come across a couple of situations where issues about exception handling were approaching the status of religion. Under the circumstances, I therefore try to offer reasonable explanations for my recommendations. Nevertheless, my ultimate goal is more reliable software, not religious discussions. If other approaches work for you, by all means use them. I remain interested in hearing from readers who have applied these and other guidelines on real projects -- successfully or not. The more collective knowledge we build on this topic, the better off we will all be.
In the following, I often mention the "state of an object". In a separate article , Dr. Harald Mueller presents a more general discussion of the problems I discuss in guidelines 1 through 3. In his article, Dr. Mueller talks about "resources". I have decided to stick with the term "object" since that is the type of resource most C++ programmers are going to be concerned with most of the time (though I will occasionally use the term "resource leak"). In Dr. Mueller's article, he defines and discusses how resources can be in either "good" or "bad" states. For myself, I originally preferred a slightly different terminology than Dr. Mueller's. Then along came the Final Draft of the C++ Standard and introduced its own terminology. Not surprisingly, the Standard is only interested in specifying requirements, so while it may be the Standard, a slightly broader terminology is useful for a more general purpose discussion. Rather than try to provide solid definitions for such overloaded terms as "bad", I will try to use terms that have fairly obvious meanings to most C++ programmers.
• undefined - when the Standard says that something is undefined, it means that the details of some particular behavior are outside the scope of the Standard. The more broadly understood meaning of "undefined" is that it "breaks" (the most cynical definition is that it works in test, but breaks at the customer's). In this context, when I say that an exception has left an object in an undefined state, I mean that all future operations on that object yield undefined behavior, including attempting to destroy the object.
• destructible - Dr. Mueller called this a "valid shutdown" state, and considered it a subset of the "bad" states. In the original article, I called this a "bad" state, but considered it better than being in an "undefined" state. In either case the point is the same: if the object is not in a "good" state, but the destructor of the object can be safely run and the object destroyed, then it is in a destructible state. As I will discuss below, this category may cover a lot of states, from just a "little inconsistent" where many operations might still work, to "really screwed up" where only the destructor will work. I decided to switch to the term "destructible" because that is what we are usually talking about anyway, and it makes more sense than overloading "bad", "inconsistent", or "invalid".
• consistent state - this is a term used in the Standard. It is the state an object is left in when a function provides what is called "the Basic Guarantee." I must admit that I find this terminology slightly confusing. I am sure that many people beside myself consider "consistent" to be synonymous with "good". The Standard makes it clear that you can not assume anything at all about the actual state of such an object. Nevertheless, there are often operations that can be applied to an object in a good state that are independent of what the current state may be -- assignment is a typical example. Furthermore, it is usually possible to make inquires about the specific state of a good object. On the other hand, I can easily show examples where it is possible for an exception to leave an object in an state where neither assignment nor typical inquiries make sense, yet the object would still be destructible. I would not consider such an object to be in a "consistent" state, yet the program that contained such an object could continue to run correctly. To my thinking, destructibility is thus the most basic requirement of an object after an exception. As a result, I have taken the position that what the Standard refers to as a "consistent state" is the same as what I call "destructible." I will elaborate upon my reasons for this below.
• initial state - in other words, it is as if the function was never attempted at all. Obviously, this is a good state for the object (by definition). Equally obvious, this is a very desirable state to be left in after an exception. The Standard requirement that a function leave the object in its initial state after an exception is referred to as "the Strong Guarantee" This point will be discussed much further in the guidelines below.
For certain examples in the rest of this article, I use a Stack template class that was originally presented by Cargill in , and elaborated upon by Dr. Mueller in . The interface for this class is shown in listing 1. While the Stack class is fairly simple, it remains a good example of the difficulties inherent in using exceptions.
A couple of brief notes about coding style: (i)I prefer to use the constant symbol null to represent the null pointer in my code instead of the current convention of using 0. I ask the reader to assume the following declaration exists within the scope of all the code that follows: const long null = 0L; (ii)I have adopted a commenting convention of //>x to indicate places in a function where exceptions are possible. Like any manual approach, this technique is error prone and very likely to miss something. It is better than nothing, however, and I have found it useful.
Table 1 summarizes the guidelines that are presented in the next section.
1. When you propagate an exception, try to leave the object in the state it had when the function was entered.
2. If you can not leave the object in the same state it was in when the function was entered, try to leave it in a good state.
3. If you can not leave the object in a "good" state, make sure the destructor will still work.
5. Do not catch any exception you do not have to.
6. Do not hide exception information from other parts of the program that might need it.
7. Unless you have a Strong guarantee of exception safety, assume that you must destroy the object after any exception.
8. Always catch an exception by reference.
9. Never depend upon destructors for functionality in any situation where fault-tolerance is required.
10. Do not get too paranoid.
We must state some assumptions before we actually start to deal with exceptions. We will assume that an exception thrown by a lower level routine indicates that the routine failed. In a follow-on article I present some goals and guidelines for throwing exceptions. While there is no way to ensure that exceptions are only used to indicate a failure condition, (and there are a couple of situations where they may not), it is probably safe to assume that most programmers are not going to accept the overhead inherent in an exception throw if other mechanisms are available to indicate normal completion.
We will also assume that exceptions are typically a rare occurrence in a well designed program. This means, in general, that the condition causing the error is not likely to be one that is easily anticipated and handled by the next higher level routine. The entire exception handling mechanism is designed to pass information from the point where an error is detected up the calling chain to a higher level of the program where enough information exists to be able to handle the error. In many cases, exceptions are going to propagate all the way to a human operator. Therefore, it is probably safe to say that the vast majority of code will simply propagate exceptions from lower level routines to higher level ones.
It is this propagation of exceptions that causes the grief and anguish. The function that throws the exception knows what state it is in and it chooses when to throw the exception. The function that finally handles the exception remains in control -- it must necessarily branch into a separate exception handling path -- but in handling the exception it recovers from the error and continues. All of the intervening functions between the one that originally threw the exception and the one that finally handles it are a problem. When an exception propagates out of a function, it indicates that the function failed. It is as if the function threw the exception, but without any control over where the throw occurs. The propagating exception terminates the function, unwinds its stack, and continues on its way.
If not anticipated and handled correctly, this propagation of an exception can leave dangling resources, objects in inconsistent or even undefined states, and in general cause more problems than the original error. Propagating exceptions destroy otherwise perfectly rational flow of control through a program. In a very real sense, exceptions are "goto's from hell". So how do we cope with them?
Guideline 1. - When you propagate an exception, try to leave the object in the state it had when the function was entered.
This is the Golden Rule of exception handling. It is not going to do much good for a program to handle an exception if the program has gone into an invalid state as a result of the exception propagating to the point where it could be handled. The C++ Standard refers to this as "The Strong Guarantee of Exception Safety". In other words, when a function provides "the Strong Guarantee", it is assuring its clients that the function will leave the object unchanged if an exception occurs.
I personally feel that writing code that meets this goal is very difficult. In an extreme case, meeting this goal might involve making a complete copy of the state of an object, attempting the operation on the copy, and then either reverting to the original if the operation fails, or removing it and going forward with the now changed copy as the object's new state. Nevertheless, I put this guideline first because it is the target that should always be the ultimate goal. How to go about this is a complicated subject, and there are more detailed articles on dealing with it . I will only give a few simple suggestions here.
Tactic 1a. Make sure your const functions really are const.
The first step in making sure objects stay in good states is determining which operations on the object actually change the state. The C++ language assists us in this regard by requiring member functions that can be applied to constant objects to be designated as const functions. As we all know however, const can be subverted, either by designating some members mutable, or with a const_cast. If your const functions really do not change the state of the object, then you can safely ignore them -- exceptions that propagate from them will not affect anything.
On the other hand, if your const functions change the physical state of the object, then you must treat your const functions like your non-const functions -- only more so. As a user, I would be very annoyed if I discovered that a const function could actually corrupt my object under some circumstances. If you discover such a function in your class, I might urge reconsidering whether it should be a const function. An example of this actually occurs in the Standard C++ Library. The basic_string function c_str() is a const function, yet it appears that an implementation is allowed to reallocate the internal character array if necessary to make room for the terminating NULL character. This could throw a bad_alloc exception. In this case const is taken to mean "logical const-ness". When a const function exhibits such behavior, it has numerous ramifications, most of them bad.
Tactic 1b. Perform exception prone operations early, and/or through temporaries.
Each of the comments indicates a statement that potentially can throw an exception. For example, the statement at x1 can throw a bad_alloc exception if there is not enough memory to satisfy the request. In this statement, the member variable nelems is increased, and then used as the size of the new request (a typical C idiom). If this request fails and throws an exception, it propagates out of push() leaving nelems set to the new value. The Stack object is no longer in a good state.
Besides doing memory allocation, statement x1 also uses T::T(). Similarly, statements x2 and x4 use T::operator=(), and x3 uses T::~T(). Each of these functions might throw an exception. For now I will ignore the possibility of exceptions from destructors, but x1, x2, and x4 are all potential problems. If we propagate an exception from one of these operations it will indicate that the push() operation failed, but in what state will we leave the Stack object?
An exception caused by a failure in T::T() at x1 has the same effect as a bad_alloc exception. If we use a temporary variable for the new value of nelems, then an exception from x1 can safely be allowed to propagate. We will assume that if T::T() throws an exception the runtime mechanism will destroy all the already constructed elements in the array and release the allocated memory (this is required by the Standard).
If one of the assignments in the loop at x2 fails, the internal state of the Stack object is still good, but we have a memory leak since the buffer pointed to by new_buffer will never be deleted. We will discuss resource leaks in more detail under Guideline 4 below.
If the assignment at x4 fails, variable top will already have been incremented. In this case, the exception will indicate that the push() failed, but the internal state of the object will have been updated as though it succeeded. Again, we have left the object in an inconsistent state.
1. Use a temporary for the new array size.
2. Use a temporary object of the template class auto_deleted_array_ptr to create an automatic variable that manages the new buffer.
3. After the new buffer is initialized, swap ownership of the new buffer between the auto_deleted_array_ptr object and the stack.
4. Delay the increment of the top variable until after the new element is assigned to the stack buffer.
The statement at line 3 swaps ownership of the old buffer and the new buffer. After the statement, the auto_deleted_array_ptr object owns the old buffer and the Stack object owns the new buffer (via its member v). The new_buffer object will then delete the old buffer when it is destroyed at the end of the block. I do it this way so that if an exception occurs when the old buffer is deleted, the stack object will still be in a good state.
Even this simple example illustrates a key difficulty in coping with exceptions. When writing a function, it is necessary to decide which operations might cause exceptions and which operations are exception-safe. Exception specifications (which are discussed in a later article) can help in this task, but they are not a complete answer. In particular, template programmers do not have access to the exception specifications of classes used to instantiate the template. Once you get into the mind set of expecting exceptions, the problem often becomes trying to determine which statements are NOT possible sources of exceptions. The only operations that can safely be assumed to never throw exceptions are the basic operations on the built-in data types. In the example above, the call to auto_deleted_array_ptr::reset() is safe because all it does is swap two built-in pointer types through a temporary.
The auto_deleted_array_ptr object automatically deals with the possible exceptions in the loop at line x2. An exception prior to line 3 will now propagate out of the function without causing either a bad state or a memory leak. That leaves only the possible exception from the assignment at line x4 to be dealt with, which brings up tactic c.
Tactic 1c. Avoid side effects in expressions that might propagate exceptions.
Side effects are a fact of life in C++. Some of them we can not see directly (and can not do anything about). Others we can see. In statement x4, whatever happens inside T::operator=() are of the former type, top++ is one of the latter. As it was originally written, an exception from T::opertor=() was guaranteed to leave us in an inconsistent state (at least) because top would have been incremented before T::operator=() was called. Since T::operator=() might throw an exception, we can avoid the side effect to top by postponing the increment.
Note that even though this makes sure top has the correct value, we can not be sure what state the Stack object is in if an exception occurs at line x4 -- it depends upon what state T::operator=() leaves the object at v[top]. If an exception thrown by T::operator=() leaves the T object in a good state, then we can say that the Stack object itself is in a good state. If the assignment leaves the T object only in a destructible state, then we must consider the Stack object to also only be in a destructible state -- we can not expect another call to push() to work if the stack buffer now contains an inconsistent object. In the final case, if an exception leaves the T object in an undefined state, then we must consider the Stack object to be in an undefined state. This means that it probably will not be possible to destroy the stack. While there is no way to tell what state the object at v[top] is in if an exception occurs at line 4, we want to make sure that if class T adheres to Guideline 1, then the stack object does also.
The domain_error class is one of the Standard library exception classes. It is derived from logic_error, which is in turn derived from exception. As discussed in the second article of this series, library exceptions should derive from the standard exception classes. Class domain_error is a general purpose base class that indicates that the domain of the attempted operation is invalid. For this example, I chose to throw a domain_error object directly rather than derive a new, Stack specific, domain_error subclass.
Guideline 2. If you can not leave the object in a same state it had when the function was entered, try to leave it in a good state.
We have several possible exception sites in this function. As before, I will ignore the possibility of exceptions from the destructors invoked in x1. Line x2 uses the default constructor for class T, and line x3 uses T's assignment operator. We can (and will) re-write this function to meet Guideline 1, but for now observe that if an exception propagates from line x2 we are in an undefined state (not even 'destructible'). The old array has been deleted, but an exception at x2 means we failed to allocate its replacement. Pointer v is left dangling and if we try to destroy the Stack object, delete will be invoked on this dangling pointer. If we do nothing else, we want to make sure that we can always destroy the object (Guideline 3 -- which we will get to later). This shows just how easy it is for a propagating exception to leave an object so messed up that it can not even be safely destroyed.
If we get past line x2 and hit an exception in line x3 we are in a more interesting position. The Stack object is now actually in a consistent state, but since we only have a partial copy done, the object is not valid. The exception propagating from the function will indicate that the assignment failed, but at this point, since we have deleted the old stack data, we can not restore the object to the state it had before the function was called. The only valid things that can be done with this stack object are to destroy it, or reassign a valid stack to it. I emphasize the word valid. This is a case where the internal state of the object appears good, and hence the typical operations could be invoked and would appear to work, but the meta-state (for lack of a better term) is inconsistent. In this case, the stack object does not represent a valid last-in-first-out ordering of the objects on the stack because it was truncated in the middle of the copy of a valid stack.
As noted, we can fix the assignment so that it meets Guideline 1, but let us assume that we could not do that.
Tactic 2a. Either reinitialize the object, or mark it internally to indicate that it is no longer usable but might be recovered.
Another reason why we want to leave objects in a good state, if possible, is that our clients might not be paying as much attention to exception handling as they should. Even though Guideline 6 (below) emphasizes that the only safe thing to do after an exception where Guideline 1 is not guaranteed is to destroy the object, our clients might handle the exception, but not realize that the object is no longer valid. In such cases, we want to make sure that any further attempt to use the object will be rejected.
Line x1 deletes the array through a temporary (auto_deleted_array_ptr::remove() is discussed below) to guarantee that the object can be destroyed in case of an exception. Line x2 is now safe, and any exception will leave the object in a valid empty state. Likewise, an exception at line x3. As noted above, we can rewrite this function to meet Guideline 1, but this is a good start.
Guideline 3. - If you can not leave the object in a "good" state, make sure the destructor will still work.
While the ultimate goal is to leave an object in a good state (Guideline 1 or 2) it may not always be possible (or at least not practical). As a last resort, we want to leave the object in such a state that it can always be safely destroyed. Never forget that as an exception propagates it will unwind the stack frame of every function it propagates through. Many times this will invoke the destructor of the very object that threw the exception. One question that should always be asked when attempting to cope with exceptions is: "What will happen if this exception attempts to destroy this object?"
As our original Stack::operator=() function showed, it is not difficult to leave the object in a state where even the destructor will not work. The most common cause of this is a dangling pointer.
Tactic 3a. Do not leave dangling pointers in your objects. Delete pointers through temporaries.
will set ap to null internally before returning the pointer so it can be deleted.
Guideline 4. - Avoid resource leaks.
The most obvious type of resource leak is a memory leak, but memory is not the only resource that can leak (I once had a program that tended to leak TCP/IP sockets). In one sense, a resource leak is just another example of a inconsistent state. In this case though, the resource that is in the "bad" state is the one that has leaked, not the one that did the leaking. For this reason, I deal with it separately.
It is not possible to discuss exceptions and memory leaks without some discussion of the auto_ptr<> template class provided by the Standard C++ Library. Auto_ptr<> is declared in header <utility>. It is a template which takes a single template argument of class type. Conceptually, auto_ptr<> is a very simple class that has two functions. First, and foremost, it holds a pointer to an object of its argument type. As the name suggests, auto_ptr<> objects are intended to be automatic objects. These are the objects for which the compiler will automatically invoke the destructors. Such objects include objects which are members of other objects. When an auto_ptr<> object is destroyed, it calls delete on the pointer it holds.
The second function that the auto_ptr<> class provides is the ability to transfer the ownership of a pointer from one auto_ptr<> object to another. This is conceptually very useful when you want to allocate an object in one function but some other function must be responsible for deleting the object later. Before auto_ptr<>, this "transfer of responsibility" had to be handled with documentation and trust. Now you can make explicit in the code the fact that ownership is being transferred. Unfortunately, these two tasks of auto_ptr<> are somewhat at odds with each other, and auto_ptr<> ends up depending upon a very subtle use of member templates in order to correctly implement the functionality described here. Most users will not need to know or care how auto_ptr<> is implemented, however; they will simply use them and everything will work.
There are a couple of things that will not work with though, and they are deliberate. The first and most obvious of these is that auto_ptr<> objects do not meet the requirements for use in Standard containers, most especially in vector<>. For this reason, auto_ptr<> is designed so that it will generate compile errors if you try to instantiate a container with an auto_ptr<> type. This often surprises people, but there are good reasons for it (which we will not go into here), so just accept it. The other thing auto_ptr<> was not designed to handle is a pointer to an array. Auto_ptr<>'s destructor calls delete, not delete. As you know, calling delete on a pointer that actually points to an array of objects results in undefined behavior. Unfortunately, this usage will go undetected by the compiler.
In the examples below, I show some uses of the standard auto_ptr<> class. I also show some uses of my own version(s) of auto_ptr<>. While most users will want to stick with the Standard auto_ptr<> class, but I decided to do my own version for a couple of reasons. My primary reason was that none of my compilers actually provide a "standard" version of auto_ptr<> yet, so I was going to have to develop my own in any case. Furthermore, I wanted some functionality in my version of auto_ptr<> that I knew wasn't in the standard version, and I didn't need some of the standard auto_ptr<> functionality that is impossible to implement without member template support.
My version of auto_ptr<> is called auto_deleted_ptr<> and is shown in listing 2. Like the standard auto_ptr<> it owns its pointer and deletes it when the auto_deleted_ptr<> object is destroyed. Unlike the real auto_ptr<>, you can not use my auto_deleted_ptr<> objects to transfer ownership of a pointer to another object. My auto_deleted_ptr<> also differs from auto_ptr<> in how its reset function works. My version returns the old pointer; the standard version has a void return and treats reset just like assignment. Finally, I created a second auto_ptr<> class to deal with pointers to arrays: auto_deleted_array_ptr<>. It is just like auto_deleted_ptr<> except that it calls delete instead of delete in its destructor. Now, what can we do with these auto_ptr<> classes?
Broadly speaking, there are three different instances where exceptions can cause resource leaks: in a constructor, in a destructor, and in a function (whether a member of a class or not). Let us look at constructors first.
If an exception is thrown by T2() during the initialization of p2, then the T2 object will be destroyed, and the memory obtained by new will be released, but not the pointer held in p1. We have a memory leak.
There are a couple of ways this can be dealt with. We could use a try block to catch the exception and attempt to release the memory, but if we have several resources allocated this way, then the nested try blocks can get tedious and error prone. An alternative is to make sure the pointers are initialized to null, and then delete them all in the catch block.
Tactic 4a: If you have raw data pointers as members, initialize them to null in the initializer list of your constructor(s), then do necessary allocations in the constructor body where a catch block can deal with potential resource leaks.
Now, since ap1 and ap2 are both auto_ptr<> objects, if an exception occurs trying to initialize ap2, then the stack unwind will destroy ap1, which will call delete on the allocated pointer. In this case, our destructor is empty since the destructors of member objects are invoked automatically.
The auto_ptr<> objects are used to acquire the resources in a manner that guarantees they will be deleted if an exception occurs. When all resources have been successfully acquired, ownership is transferred to the class itself. This is just Tactic 1b applied to resource acquisition. I see this as a transitional strategy for constructors, however. In the long run, I suspect that the use of raw data pointers as class members will diminish in favor of auto_ptr<> style objects. This simplifies maintenance as well as the problems of coping with exceptions. If you worry about performance, keep in mind that all the operations of auto_ptr<> are inline functions. Most of these are one line functions that any decent compiler should have no trouble handling.
Finally, we can have resource leaks in destructors. As a general rule, we do not want to throw (or propagate) exceptions from destructors. Nevertheless, we can not always prevent it, so let us take a look at a simple problem. Consider our first example of class X above. We have two pointers to two different types of objects. Everything has gone well, and now the destructor of X is invoked. It is pretty simple.
Not much to go wrong here, but assume that it does -- say the T2 object throws an exception when deleted. Like constructors, destructors are special functions for the exception runtime mechanism. When an exception occurs in a destructor, it is treated like an exception in a constructor, i.e. all complete sub-objects that still exist are destroyed (in reverse order of their construction) and then the memory deallocation function is called, if needed. Exactly the same problem occurs here as it does in a constructor. The exception from the destructor of T2 will terminate the body of the destructor without deleting the resource held by p1. The solutions are likewise similar to those applied to a constructor.
For example, we can attempt to catch the exception and guarantee that other resources are deleted. Unlike the constructor however, there is no way to organize things so we can cover everything in a single catch clause -- at least not without more work than is worth it. Once again, we turn back to the "acquisition is initialization" strategy and use auto_ptr<> objects. If all our member variables are auto_ptr<> objects then our destructor is empty anyway, so let us assume otherwise.
This may seem a little silly, but it does work. We transfer ownership of the resources to the two temporary objects (we create them in the same order that p1 and p2 are declared so they will be destroyed in reverse order). When the destructor body exits, these objects are destroyed, deleting their pointers. If an exception occurs in the destruction of t2, then the stack unwind will still destroy t1.
Guideline 5. - Do not catch any exception you do not have to.
There is an old C rule of error handling (actually it probably goes back to the Countess Ada Lovelace) that states: "do not test for any error condition you do not know how to handle." Like most cynical proverbs, there is a certain amount of wisdom in this. In C++, we now have a standard way to handle any error condition -- throw an exception -- but this just shifts the burden of the problem. The basic truth remains: it is a waste of time (yours and the computers) to catch an exception you do not know how to handle.
Tactic 5a: Rewrite functions to preserve state, if possible.
This is similar to what we have to do in the pop() function. In that case we do not have any choice; in push() we do. Guideline 5 says that if we can arrange our functions so that we can avoid writing try/catch blocks then we should do so. It leaves us with cleaner code and it is more efficient to let the exception just propagate than it is to catch and rethrow it.
it is not clear that the first form is necessitated by the possibility of an exception. We run the risk that during maintenance, some experienced C programmer (but new C++ programmer) will take a look at the two lines and decide that whoever wrote them did not appreciate the compactness of expression possible in C++ and change them back into the latter. This may turn out to be one of the most annoying drawbacks to using exceptions in C++, i.e. a great many of the cherished idioms from C are going to have to be discarded. Instead, we are going to have to use a much more deliberate (and verbose) style that allows us to maintain better control over the state of our objects in the presence of exceptions.
we have no guarantee that top actually was incremented before the exception occured.
Generally, I still think you are better off rearranging code, but that means in order to avoid the maintenance problem, we must document every place in our code where we think an exception is possible, and especially everywhere we have changed code to make it exception safe. I use comments of the form //>x. This is not a particularly good solution, but it is better than nothing.
Tactic 5b. - Always use a catch(...) block to cope with propagating exceptions.
This is pretty obvious for a template class like Stack, where we have no idea what kind of exception might be thrown by T, but in general, even if we know (or think we know) what the actual exception type is, if we are not actually handling the exception, then we should use a catch (...) clause.
Tactic 5c. - Do not "handle" any exception that can not be "fixed."
This tactic falls between those for just coping with propagating exceptions and those for handling exceptions. I put it here since it is a special case of the more general Guideline. The idea is to avoid getting yourself into an infinite loop where you "handle" an exception without fixing the problem (usually by just ignoring it), and then retry the operation again. This is especially a problem when your code depends upon user intervention to actually "fix" the problem. There are few things in life more frustrating than computers that tell you to do something that you either can not or do not want to do, but refuse to let you out of the mode they are in unless you comply with their instructions. If you put error messages up to the user, be sure your dialog box allows them to cancel the attempted operation as well as retry it. If you do retrys internally, make sure you put a limit on the number of retrys you attempt before giving up and propagating the exception to a higher level.
Tactic 5d. - If you get stuck, call terminate().
This is not really about handling exceptions, but it does have something to do with coping with errors. There are places where throwing an exception does not make sense, and the only possibility left is to end the program. An obvious circumstance where this happens is in a user defined version of unexpected_handler. Unexpected_handler must either throw an acceptable exception, or end the program.
Before exceptions, the normal way to abnormally terminate a program was by calling the C library function abort(). In the new C++ world, we should call terminate() instead. Terminate() just calls terminate_handler. In the default case, this calls abort(), but the user can replace the default terminate_handler with a program specific version. So call terminate() to allow any user defined terminate_handler to run.
Guideline 6. Do not hide exception information from other parts of the program that might need it.
Just to reiterate the obvious: the purpose of exceptions is to pass information from the point where an error is detectable to a point where the error can be handled. If you throw a different exception rather than rethrowing the original exception, you want to make sure you are increasing the the possibility of the exception being handled by doing so.
Tactic 6a. - Always rethrow the exception caught in a catch (...) clause.
Tactic 6b. - Rethrow a different exception only to increase the level of abstraction or capability.
At first reading this seems to make sense. Foo() invokes some operation that might throw a private exception type, which is caught and handled. To be on the safe side, foo() includes a catch-all block just to cover the bases. The problem is that when foo() throws the generic exception in the catch-all block, it effectively destroys all the information in the original exception. This information presumably indicated what the original error was and might have been of use to a higher level routine that was willing and prepared to deal with an error of that type. Now, all that propagates upward is a self-fulfilling prophecy, and the program will probably terminate because nobody knows how to handle an "unknown exception".
In our ongoing Stack example, there are several places where we use the new statement. Under the C++ Standard, new will throw a bad_alloc exception if the memory allocation fails. In the second part of this series of articles we add a private exception class to Stack that is derived from bad_alloc. In Stack<T>::AllocationError we include some additional information besides that available from bad_alloc alone, including the new size of the stack being allocated.
In this case, our catch (...) clause will not only catch the bad_alloc exception as the (erroneous) comment indicates, but we will also catch any exceptions thrown by the T::T() constructor. If the new expression fails because of an exception in the latter, we will hide that exception with our version of bad_alloc. While it is true that either case will indicate that the function failed, hiding the original exception means that any higher level routine that handles the Stack<T>::AllocationError exception will be solving the wrong problem.
Tactic 6c. - Make sure one catch block does not hide another.
When the exception runtime attempts to locate a handler for an exception, it tries the handlers in order. Unlike function overloading, where the best match from a set of possible functions is found, an exception handler is found on a first match basis. This means that you always want to put more specific handlers before more general handlers. Handlers specifying base classes (or references to same) must come after those for more derived classes. Obviously, any catch (...) clause must be the last handler of a sequence. The compiler will almost certainly complain if the catch (...) clause is not the last one, but it may not generate an error message for other incorrect orderings, so beware.
Guideline 7. Unless you have a Strong Guarantee of exception safety (Guideline 1), assume you must destroy the object after any exception.
Now we start getting into guidelines (and tactics) for actually handling exceptions. Ideally, when you handle an exception, you correct whatever was wrong and then redo the failed operation. In order for this to work, you have to be sure that the operation(s) which failed left their object(s) in the state they had before the operation(s) was attempted. This is Guideline 1, and is what the C++ Standard calls the "Strong Guarantee". If you can not say for certain that Guideline 1 is being followed, then all bets are off. If Guideline 2 has been followed, you might be in a position to reuse the object, but in general the only really safe thing to do is destroy the object and start over.
we are probably safe in re-using the string object (see Tactic 1a). The stack<> is another story. If parse() guarantees to follow Guideline 1 (The Strong Guarantee), then everything is fine. Of course, for parse() to be able to make this guarantee, it depends upon everything that it uses, including all string and stack<> functions, also providing the Strong Guarantee. Since we are assuming that not all of our stack<> functions provide this guarantee, we can not assume that parse() does either. So we come to the following tactic.
Tactic 7a. -- Put everything that needs to be destroyed inside the try block.
By putting the declarations of in_str and results inside the try/catch block, we guarantee that they will be destroyed by the stack unwind BEFORE the catch clause is entered. We might want to keep in_str outside of the loop if we want to have the user's input still available inside the catch clause.
Tactic 7b. Explicitly destroy and re-construct objects which might be damaged by exceptions.
This uses the explicit destructor call mechanism to destroy the object in place, and then uses the placement form of operator new to reconstruct the object. Obviously this is really ugly compared to just letting the compiler handle it, so I consider this a last resort approach. Nevertheless, keep it in mind. It beats having your program blow up because you tried to reuse an object that was in an inconsistent state.
Guideline 8. Always catch an exception by reference.
means that the call to what() is a virtual function call, and it yields the string used to create the domain_error object.
Guideline 9. Never depend upon destructors for functionality in any situation where fault-tolerance is required.
As a general rule, we do not want exceptions propagating from a destructor. There are two reasons for this. First, there is simply a semantic problem with deciding what it means for a destructor to have an exception. For ordinary functions, an exception typically means the function failed. What does it mean when a destructor fails? Certainly, it should not mean that the object is left in a usable state since it was not going to be usable if the destructor succeeded. In most cases the memory for the object will disappear anyway, whether the destructor succeeds or not. In other words, there is not much we can do about handling an error that occurs in a destructor, and we ordinarily want the destructor to finish anyway, so there is not much point in signaling errors from a destructor, even though exceptions give us a way to do this.
The second reason for avoiding exceptions in destructors is more fundamental - they are likely to abort the program. In a sense, destructors are part of the exception handling mechanism itself. Destructors are invoked by the exception handling runtime as part of the stack unwind process. If a destructor throws an exception during an exception stack unwind, then the Standard says the exception handling mechanism gives up and calls terminate(). For this reason, other writers have taken the position that destructors should never throw or propagate exceptions[2,3]. I do not go quite that far, but the following tactics should apply under most circumstances.
Tactic 9a. Do not throw exceptions from a destructor body.
This is the principal behind Guideline 5 again. Clearly, there is no sense in testing for error conditions in a destructor body unless they can be handled right then and there -- otherwise ignore them (or call terminate()).
Tactic 9b. Do not arbitrarily handle all exceptions propagating from a destructor.
A program captures medical images from a Computed Radiography (CR) scanner and transfers them over a fiber optic network to a central image server. If there is any problem with the network, or with the image server, the program is required to save the image to local disk, generate a message on both the local console and the system administrator's console (a separate network is available for system administration tasks), and enter an error state that prevents any more images from being captured until the problem is fixed and the image saved on disk is transferred to the central server. This is necessary because the X-ray plates used by a CR machine are erased by the scan -- once scanned, the image must be captured or it is lost forever. Assume the network connection is encapsulated as an object (call it an endpoint). If the endpoint destructor is called, and the connection is still open, the destructor will attempt to close it. If some error occurs it seems reasonable, given the nature of this program, that an exception should be thrown to indicate a network problem to higher levels.
This would seem like a perfect case for having a destructor throw an exception, but maybe not. A closer look at this program reveals that under normal circumstances the network connection should always be closed before the endpoint is destroyed. If the connection is still open when the destructor is invoked, it probably means the endpoint is being destroyed as a result of some other exception. If this is the case, then the last thing we want to do is throw another exception. In fact, we may be trying to destroy the endpoint as a result of a stack unwind that resulted from an exception thrown by another network function call. We want this exception to propagate.
So back to the question of whether a destructor should handle all possible exceptions or allow them to propagate. Destructors being the type of functions they are, it may make sense to ignore a lot of errors in destructors (i.e. catch the exceptions and not rethrow them). Nevertheless, at some point in coding a class or library, we have to acknowledge that our users will probably have a better view of the big picture than we do. There has to be a limit on how much we try to handle at a given level. This is especially true for destructors. The person who uses our classes has to accept some responsibility for how they are used. This means that any program that has to be fault tolerant must be designed and coded with special care regarding the types of exceptions it has to guard against.
If our medical imaging program is written correctly, then it will not depend upon destructors for normal functionality. The remote file will always be closed before the file object is destroyed; the network connection will always be closed before the network object is destroyed, etc. Exceptions are possible -- in fact the program may depend upon them -- but their occurrence will be anticipated as part of normal design, and they will be handled outside of the destructors. We are left with something of a paradox: the more fault tolerant a program has to be, the less likely it is going to have to worry about exceptions from destructors.
on esthetic grounds alone, but there is a practical aspect as well. Templates are but one example of a case where we have no idea what kinds of exceptions are possible from the operations being invoked on the objects used to instantiate the template. There are times when we have to assume that the user knows what she is doing and stay out of the way. This goes even for exceptions propagating from destructors.
Guideline 10. - Do not get too paranoid.
As a final point, I have noted that it is possible to get paranoid when trying to deal with exceptions. Maybe this is only a problem for me because I have spent so much time lately worrying about exceptions. Still, I am willing to bet that other people are also going to run into this.
If the constructor in the catch clause throws an exception, then we have left our Stack object in an undefined state. After destroying the object at v[top] we can not even expect the destructor for Stack to work. We must assume that the constructor will be able to reinitialize the object at v[top].
If you find yourself writing code like this, take it out. As we discussed in the beginning, exception handling is something that must pervade the entire program. At some point you have to turn the problem over to the user. Ultimately, only the application developer is in a position to really decide how to deal with certain errors. More often than not, the application will have to seek help from a human operator. In the final analysis, often the best we can do in handling an exception is to make sure our software stays together, and then propagate the exception and let a higher level deal with it.
As shown in this article, exceptions raise many issues that either were not there before, or which had much simpler solutions. Many of these Guidelines and Tactics can be illustrated with simple examples, but are not simple to apply in real practice.
The good thing about exceptions is that not every program needs to be truly fault tolerant -- in fact, very few do. What is much more important is that a program be robust. A robust program is resistant to errors -- it either works correctly, or it does not work at all; whereas a fault tolerant program must actually recover from errors. There are obviously different levels of "robustness." For years, I have liberally sprinkled my code with "assert" statements to make them more robust. Since all an assert statement usually does is print a message and abort the program, there are those who might question whether this actually qualifies as an improvement in robustness. Certainly, this is not acceptable behavior in a shipping application. For this reason, assert statements are usually used only for debugging and disabled in the final build of an application.
Before exceptions, the only alternative to a deliberate abort was to return error flags and check them religiously. Exceptions provide a third possibility. If an exception is not handled at some point in a program, it will propagate out of function main() and invoke terminate(). Thus, an un-handled exception has much the same effect as an assert statement. Conversely, the program can choose to handle the exception (if only to provide a more graceful exit). For this reason alone, programmers are going to insist upon throwing exceptions, especially in library code -- it relieves them of the problem of deciding whether to abort the program, or not. As noted in the beginning, throwing exceptions is easy, coping with them is difficult.
The simplest way to start out coping with exceptions is to have a single try/catch block in the main() function to provide a meaningful error message and a graceful exit of the program (Guideline 5 applied to the entire program). A program written this way may not be any more robust than a properly written C program, but that level of robustness will have been obtained with a lot less effort (virtually none), and a lot less code. Just think of all the if statements that will not have to be written.
From that point, developers can start to actually apply these guidelines to libraries and functions in order to bring them up to a point where they can be used in a fault tolerant program. We have to be careful not to rush into using catch clauses to handle exceptions or we run the risk of falling back into the problem where we think the program is running fine but in fact it has entered an erroneous state. Nevertheless, when used correctly, exceptions can definitely improve the reliability of our programs. As the examples in this paper have shown, this may take a lot of work, but developing reliable software usually does.
1. Tom Cargill, "Exception handling: A false sense of security", C++ Report, Vol. 6, No. 9, November-December 1994.
2. Harald M. Mueller, "10 Rules for Handling Exception Handling Successfully," C++ Report, Vol. 8, No. 1, January 1996.
3. Scott Meyers, "How to Navigate the Treacherous Waters of C++ Exception Handling", Microsoft Systems Journal, Vol. 10, No. 11, November 1995.
4. Jack Reeves, "Migrating from C to C++", C++ Report, Vol. 7, No. 7, July-August 1995.


text:
FeaturedIndustry NewsNews
Ouya delays retail launch — fixing sticky controller
Jeff Chabot
For those of you anxiously awaiting the Ouya's arrival to stores on June 4th, you'll have to wait another 21 days until Tuesday, June 25th. The original drop date has been delayed by the startup game company, giving Ouya a chance to manufacture more units but also to fix a sticky controller issue Kickstarter backers have complained about. The problem, apparently, was due to the size of the hole the button sits in under the faceplate (exactly which button(s) not specified). Ouya CEO Julie Uhrman told JoyStiq, "we've increased the size just a little bit, so now the buttons don't stick under it." Ouya backers can request replacement controllers from the company's customer service.
This morning's press release from Ouya also boasts $15M in new funding led by Kleiner Perkins Caufield & Byers, most of which will be used to better meet anticipated retail demands, as well as improve the Ouya game development community.
Ouya will be available for purchase in the U.S., Canada, and the U.K. on June 25th. The console will sell for $99, with additional controllers selling for $49.99. Ouya consoles can be pre-ordered through Amazon and other retailers. (Note, Amazon is still posting the June 4th release date.)
Spotlight on Ouya
Review+Interview: Banner Saga Factions
Ouya console launch to include Final Fantasy III
kickstarter Ouya
Monaco: One Vault at a Time
The Breakdown: FEZ
Interview: The crew at Yacht Club Games talks Shovel Knight (Part I)... May 3, 2013 | Zebulon Rogers
Ouya console launch to include Final Fantasy III... July 31, 2012 | Sam Jordan

redpajama_set_name: RedPajamaCommonCrawl


text:
City Councilman Matt Schellenberg represents all that is wrong in Jacksonville politics (rough draft)
City Councilman Matt Schellenberg represents all that is wrong in Jacksonville politics, amoral, ignorant and mean.
When talking about the half cent sales tax to help Duval County's resourced starved schools he said, the School Board should withdraw its request for a referendum and demonstrate it is fiscally responsible by reducing bureaucracy and selling its downtown headquarters property on the riverfront. He said the district also must show it "has the backbone and leadership" to consolidate schools.
Schellenberg said the city could find a "fair-minded solution" that shares some of the annual contribution the JEA gives each year to city government, but the case hasn't been made for sales tax increase.
"Quite frankly, they had a disastrous roll-out because they didn't engage the public," Schellenberg said. "Basically, they dismissed that, and I think that's appalling."
https://www.jacksonville.com/news/20190601/sales-tax-referendum-might-slide-to-2020
First fiscal responsibility by reducing bureaucracy and by selling its downtown riverfront headquarters are nothing but two canards that are thrown out to distract. Who does he want to get rid of? What position does he think we have to many of? I bet if pressed he wouldn't be able to name a single person or position. This is what ignorant people say because they heard other ignorant people say it. As for the school board building, it is completely paid for and nobody is offering what it would take to replace it elsewhere. Selling it would be a colossal mistake.
Then he calls for a fair minded solution from a city that has never been fair minded to education, saying perhaps JEA which does not pay property tax could be made to pay some of its city contribution to the district. This is ironic because I couldn't see Curry ever allowing that money to be touched and JEA just said they may have to both increase rates and scale back the contribution and Schellenberg has to know that.
https://www.jacksonville.com/news/20190528/jta-considers-fare-hikes-as-june-public-meetings-set
Then he talks about the disastrous roll out and I think it could have been done better. Months ago at one of the many meetings that Schellenberg could not be bothered to attend, I could see what they were doing and asked it it was going to be a sales tax or millage increase and was kind of blown off. It would have been a lot better had they just admitted that was their plan then. That being said there have literally been about 20 meetings all over town and they solicited input on-line for over a month. Did Schellenberg want them to go door to door? What's appalling is his complete lack of facts and up to now interest.
Then do you know what Schellenberg has done during his term in office to help public schools? ... crickets... nothing, which means while turning his back on public education, he has the nerve to complain when the district finally decided to do something. He should shut his pie hole and allow the people of Jacksonville to decide.
There is absolutely nothing the district could have done that would have satisfied Schellenberg because like Curry and more than a few others in City Hall, I believe he wants our schools to fail.
This guy, ignorant, mean and amoral represents all that is wrong in Jacksonville.
Bibliophile June 2, 2019 at 4:25 PM
Schellenberg wants to sell JEA. Why not give the proceeds to DCPS? As for not making the case to the public I'm not surprised Schellenberg & Curry are willfully ignorant on this issue. They're not big on charettes (as evidenced by their $18M buyout of the Landing without public input)so you have to put up giant flashing billboards & 30 second tv spots to catch their short attention spans.
Can we be honest, Jacksonville really hates black ...
Mayor Curry's wife understands the schools need th...
DCPS staff disrespected by Mayor Curry and the Cit...
Let me explain why safety concerns don't move Curr...
If Florida is the nation's ground zero for school ...
Lenny Curry's gas lighting continues
Scott Shine's recent public records request, I thi...
Scott Shine asks the district for my correspondence.
Just who has Gary Chartrand donated to in just the...
Mayor Curry tweets support for charter schools whi...
Mayor Curry continues to tell lies and mislead abo...
Scott Shine's lies and half truths about the refer...
World's worst school board member Scott Shine, jok...
Lenny Curry stabs the city's children in the back ...
Gary Chartrand shows he doesn't care about parents...
Does the entire city serve the Civic Council
The Civic Council's pet charter schools already ge...
Fighting against the referendum has absolutely not...
Gary Chartrand only wants extra money for his char...
Gary Chartrand's lies and bad ideas, Sunday editio...
How Gary Chartrand hoodwinked a town to push his t...
Lenny Curry and the civic council are also fightin...
Lenny Curry and the civic council's con job is wea...
Superintendent Greene and board chair Hershey's a ...
Was councilwoman Boyer rewarded for selling out th...
Now Mayor Curry and the city council care about ta...
We aren't being led by the mayor and city council,...
We should let the local democratic party know that...
Tommy Hazouri sells out the city's schools, childr...
The Civic Council doubles down on its attack again...
The city council doesn't seem to realize what a pr...
Governor DeSantis comes out for the DCPS tax refer...
Curry wants public schools to fail and charter sch...
There haven't been a lot pf profiles in courage an...
TFA wants to charge the district 14 thousand per t...
Teach for America rears its ugly head in Jacksonvi...
%$#& Tommy Hazouri, %$#& that guy!
DCPS teachers and parents it is time to stand up f...
Momentum picks up to have Scott Shine removed from...
Who is working in Duval County's charter schools?
Scott Shine was ridiculously bad while on the scho...
Meet our lords and masters the Civic Council
Jason Fischer goes after a reporter for supporting...
State board member threatens DCPS
Curry and the council's specious reasons not to su...
City Councilman Matt Schellenberg represents all t...
Florida is starving its public schools is by design
The notion Education Commissioner Corcoran cares a...


In the restaurant industry, expanding to more than one location isn't uncommon, but often, it comes with added pressure, since there's now more staff to hire and manage. Then, of course, there's the large financial investment that comes with opening a restaurant.
Yet, with added stress comes an abundance of opportunity. The private events sector is booming — according to research done by Gather, it's a major revenue driver within the industry, making up 20-30 percent of revenue for restaurants. This means companies with additional locations have even more hosting opportunities. While incorporating a private events business seems like a no-brainer, planning and hosting private parties can be uncharted waters for a lot of owners. So, how can restaurant owners learn to navigate the private events business at more than one location without dropping the ball or simply, going crazy? Check out the below tips and suggestions.
It's true, private events can make up a piece of the revenue stream for restaurants, but 70-80% of profits still come from the bread and butter of the business: casual diners. Before jumping into private events, make sure the restaurant is off the ground and running. Take your time building that initial clientele, and the rest will follow. Private events can be an undertaking, so a great first step is to get people excited about the dining experience.
For each location to reach its greatest potential and be successful, it needs to be treated as a separate entity within the company. Although brand awareness is the goal, each restaurant will be in a different location, could possibly reach different clientele, and have a different menu, so it's important to play to that location's strengths and market it to maximize its potential.
Does each restaurant have the same menu, but specials change based on location? Market those specials as something new and exciting each month or week (dependent on the timeframe), driving foot traffic and an increase in event leads. Or maybe each location has a different flare and ambiance with a unique menu and vibe? Treat each restaurant as if they aren't connected, making them a unique hotspot for private dining. Take into consideration all aspects of the restaurant when properly marketing each location.
Hiring the right management team can be difficult. They're expected to keep all aspects of the restaurant running smoothly, which can be a lot of pressure when you add managing private events into the mix. Because each restaurant location is just one branch of the company, it's important that management at all locations work with one another, ultimately understanding that bringing in business for the company is the main goal. Knowing what is going on across the board is key. During the interview process, look for people that are willing to go the extra mile, can work well with others, and are ultimately looking to help you grow your business. They'll need to work as an extension of yourself and accurately represent the company's values.
Using the same technology platform across multiple locations creates efficiency and consistency when planning private events. Mistakes are minimized and communication is improved, as paper trails become a thing of the past and all information for each location is stored on one platform. No more worrying about lost forwarded emails, because all communication between employees and clients can be traced using the software's portal, minimizing mistakes due to miscommunication. Using events software also allows owners and managers insight into all the restaurant's locations, which means they'll have the ability to book a larger volume of leads.
Sometimes one location might be booked due to a high volume of parties during that day or time period. This is huge for driving sales across multiple locations, because according to the Harvard Business Review, businesses who contact a potential client within an hour of an initial inquiry are 60 times more likely to close the deal with that venue. Additionally, customization is key when working with clients who are trying to differentiate the experience for their guests. By using a software like Gather, managers handling client requests are able to easily design custom menus and create estimates based off of those requests without starting from scratch on an Excel spreadsheet.
Opening multiple locations is a key first step in growing a business, but in many cases, owners are deterred from making this decision due to the overwhelming added stress and financial obligations that go along with it. Using the tips above should help encourage growth, unlocking untapped revenue through private events at each new location.


On Tuesday and Thursday of next week (20/22 October), TWP are delighted to welcome Ola Animashawun to Nottingham to lead two workshops called Taking the Stage. Ola has worked at the Royal Court for the last fifteen years, championing new young writers and being an instrumental part of the development scheme Critical Mass. Find out more about Ola by following this link to a video in which he talks to the BBC about how to get started when writing a play.
There are a few places left on this workshop, so please contact bianca@theatrewritingpartnership.org.uk or call 0115 9474361 to book yourself a place – you won't be disappointed. Go on – inspire yourself, and meet other people with an aspiration to explore the stage.
If you can't make Northampton on Saturday, but you're interested in some culture, check out the FD2D weekender.
Talawa Theatre Company is exploring new ways to share and discuss new writing through live streamed rehearsed play readings.
Talawa's series of play readings showcasing the best in Black British writing- is back at the Young Vic for its second series. Flipping the Script is your chance to hear a few of the thousands of different voices that make up the Black British experience.
We understand that many talented writers, both established and emerging, live and work outside of the capital and can't be at the Young Vic in person, so we are streaming the readings online. With continuous chat room discussion throughout the evening we enable writers of all backgrounds the opportunity to watch, listen and participate.
After a fantastically successful pilot programme, Newark and Sherwood District Council were awarded Arts Council funding to develop Visible: opportunities for people over fifty to engage in inspirational and stimulating creative ventures. Visible is being launched with an exciting collaboration between NSDC, Manchester Camerata and Thoresby Gallery. Book your place before it's too late!
testing style etc. – will a posterous autopost obey the laws of CSS?
TWP's springboard for the year ahead.
2 – 27 October 2009.
Don't miss out – check our blog for details.
On the 2nd and 3rd of October 2009 Theatre Writing Partnership, Stan's Cafe and Derby LIVE brought a two-day adventure to the City of Derby. The first day was a city-wide adventure – a kind of treasure-hunt with clues and tasks that produced images, sounds and creative writing in the morning, and then a coming together of participants to produce scripts and monologues in the afternoon. The second day brought a director and 4 actors to the material, producing a performance and presentation that evening: A City Staged.
Listen to Kate Chapman explaining the first day: A City Adventure.
This was a bold and unusual experiment in theatre writing which was very exciting to be a part of, and we want to bring you just a taste of the experience through the media (audio, video, and images) produced by our two social-media documenters: Hannah Nicklin and the excellent Christian Payne (Documentally).
The days would have been nothing without the participants, who though not always privy to the big picture, traversed the tasks given to them with enthusiasm. Here we have an interview with several of them, just back from the morning's adventure.
The material they produced was then wrought into shape by TWP's Artistic Director Kate Chapman, and a team of four actors, here's an interview with Gary, one of those actors, and with Kate, just half an hour before the presentation was performed.
We will leave you with an interview with Rochi Rampal, one of the performers, just after the performance finished, and with Jayne, one of the City Adventure participants reflecting on the feeling of seeing her writing staged.


Well, we managed to survive for a whole two weeks without the hot tub. Yes, I know you're surprised, but we swapped one form of water container for another. We're just back from two weeks in Turkey and replaced the hot tub with a swimming pool.
Whether the water is hot or cold there is something very comforting in immersing yourself. Of course, in a warm country, it's the 'cooling down' affect but here at home there's an almost 'back to the womb' like quality in sitting in a hot tub. Do you remember those days before you were born?? No, of course you don't, but you can probably imagine – no mortgage, no kids, no stress! What bliss.
Sitting in the hot tub seems to take away all the strains and stresses of the day and you emerge feeling totally relaxed.
What I'm not quite so relaxed about is the fact that the One Show have decided that our little film on hot tubs is worthy of being shown again on Thursday 18th July at 7 p.m. Will my embarrassment never end!
Catalina Spas is a family-run business with 17 years worth of sales in the UK and across Europe. We are a constant forerunner in our design and implementation of the latest features available for both private and commercial sector spas. Here is a selection of some of the unique features that Catalina has pioneered in the European market.
This is a fantastic feature for evening spa sessions. Whether you are relaxing with a glass of wine and a movie or have friends over for a party, the LED waterfall sets the scene. A standard feature on all the Sunset Constellation range, the water pressure can be controlled to change the waterfall to your liking.
Another party-piece is the illuminated jets. Their underwater features are more than just mood setting lights. These are the finest hydrotherapy jets available. They are designed completely with bather comfort in mind and have the functionality of inter-changeable pressures to offer the bather a bespoke massage to their liking!
Stunning features at the night-time, these little waterfalls offer nothing more aesthetic exuberance, but it's worth it! These fantastic waterfalls 'pop up' out of the shell when turned on, and the back-light in the housing shines a beam of light through the waterfall offer a 'Las Vegas style' display. Great little party features.
For the full-on party-piece, perimeter lights installed around the outside decking of the spa area could be the perfect idea. This is ideal for those who want to make a featured area around the spa – perhaps with a bar area, loungers, stools, plants, extended decking and more.
Catalina spas provide the most cutting-edge spa features on the market with a comprehensive range of spas to suit every budget, requirement and setting. Therefore, make sure you check out their range today.
The first thing to think about when buying a hot tub or spa is why you want it in the first place – is it simply for you to share relaxing, romantic evenings as a couple? Are you a party animal, looking to add that wow factor to your gatherings, or will you probably enjoy it on your own, soothing away those aches and pains?
There are several sizes of hot tub and the size you choose will undoubtedly depend on how many people are likely to use it, available space and your budget.
You also need to consider the force of the jets which are an integral part of each spa. Are you looking for a soft bubbling tub to help you relax or would you prefer a more forceful jet to pummel those aching joints?