http://www.accu-usa.org/2001-03-Main.html
By Reg Charney
I am about to start a project in which I hope to use C++’s exception handling mechanism. I say “hope” because writing exception-safe code is not as simple as writing code that produces invalid results if exceptions are thrown. The tradeoffs are between writing clearer code that works predictably under almost all circumstances but that may be slightly slower against code that may be faster, but produces unpredictable results under stressful conditions such as running out of resources.
Listing #1 shows a simple example that is not exception safe. See if you can identify some of the problems. A more exception safe version of this example is shown in the Listing #2.
class Hdr { }; // assume variable header size class Txt { }; // assume variable text body size class Msg { // composite class int main() |
Listing #1: Unsafe Exception Example
Types of Exception Safety
A piece of code can be exception unsafe, neutral, or safe. Exception unsafe code leaks resources and/or leaves partially constructed objects around after an exception is thrown. Exception neutral code passes back all exceptions to the caller. Exception safe code works correctly when exceptions occur and does not leak resources or leave invalid object fragments. There is also basic, strong and no-throw exception safe safety guarantees. The basic exception safety guarantee ensures three things:
- Destructors don’t throw exceptions
- There are no resource leaks
- The state of variables or class instances are valid and useable.
The strong exception safety guarantee adds a fourth rule:
- The state of an instance is the same before and after if an exception is thrown.
The no-throw exception safety guarantee adds the most stringent fifth rule:
- The piece of code will not throw an exception.
Guidelines
To make this all happen, Herb Sutter [1] has given a series of guidelines:
- Ensure that no exception escapes from a destructor, overloaded operator delete() or operator delete[]() .
- Move all code that might cause an exception into another function or try/catch block; and only when all that code is executes correctly, change the state of the instance.
- Give each code fragment (module, class, function) a single well-define responsibility.
- Exception safety is a design consideration. It must be built in, not added as an afterthought.
- Separate out memory allocation from object construction and destruction.
- Use the Resource Acquisition Is Initialization idiom to isolate resource allocation and management.
- Use the Acquisition Before Release idiom to ensure that resource is not leaked.
- An object may own at most one object (see Griffiths [2])
For basic data types like int and pointer, this is always the case.
The rewritten example in Listing #2 uses these guidelines and idioms to make the example exception safe. Given the complex problems it solves, the implementation is much cleaner than one would expect.
#include <algorithm> using namespace std; class Hdr { /* … */ }; // assume variable header size class Msg { // Composite class namespace std { // extend std::swap for Msg objects by int main() |
Listing #2: Safe Exception example
Let me know is you see anything that interests you.
References
- Exceptional C++ by Herb Sutter, Addison-Wesley, ISBN 0-201-61562-2
- Here Be Dragons by Alan Griffiths C/C++ Users Journal, March 2001
- The C++ Programming Language: Special Edition by Bjarne Stroustrup Addison-Wesley, ISBN 0-201-70073-5
Editorial
By Reg. Charney
More of the Same
In the newspaper world, there is the concept of the “dog days of summer” when there was no news. In terms of trends, that about describes what is happening now. Everyone is waiting for the other show to drop. Are we heading into a recession or a recovery. I am here to tell you that nothing much has changed from last month. Things are still slowing down, but at a very gradual rate. Since you have all heard this before, I am not going to repeat myself, but give over my usual space to a more comprehensive book review from Allan Kelly.
Book Review
By Allan Kelly
Generative Programming by Krysztof Czarnecki and Ulrich Eisenecker, Addison-Wesley, ISBN 0-201-30977-7.
My review copy of this book was handed to me with the cautionary tale that another ACCU regular had declined to review it saying “a good review would need an entire book itself!”. I’ll try to give you something of the a flavour of this book so you can decide for yourself.
The book is split into three parts. In part one, the authors set out their thesis that there is a difference between engineering for re-use and engineering with re-use. If we wish to achieve re-usability, we must look at ways of automatically generating systems using code generators, libraries, frameworks and other tools. While no generator will be applicable to all problems we can identify families of problems within a domain which have common abstractions. This introduces the concept of domain engineering and the idea of dividing our effort between component system engineering and application system engineering . This is an idea I have practised myself so it is good to see it codified and explored.
Part two is a chapter by chapter review of technologies that play to this paradigm. The reviews help further the central thesis and show how the technology under review can be applied. While interesting, it does add a lot of material (400 pages out of 800) which isn’t core and often doesn’t add to their argument.
Part three give examples. Unfortunately these are laboratory examples, and each one is a well known problem: list, matrix and bank accounts. The true value of any new technique is not in how well one can use it to implement a well understood problem but how well it deals with those which we only come to understand as we apply the technique. I would rather have seen a case study of a real project.
In the name of engineering for re-use the authors attack every possible point of variance within a system hoping to make it more re-usable. Looking for points of variance is a useful technique, but when taken to extremes I think it detracts from the maintainability of a system – the cure is worse than the disease.
In part the authors response is that since the code should be generated, we don’t need to maintain it. However, this just moves the problem to the maintenance of the generators or domain specific language (DSL). Here the lack of real world contact shows: maintenance issues, problems with DSLs, the high failure rate of framework projects and several other issues are not discussed at all..
Domain analysis and engineering is a fresh way of looking at a class of problems, and would certainly be essential if we wish to produce a framework with code generators but I’m concerned that it is also a Catch-22 : if we define the domain too broadly then we will never escape analysis paralysis ; however, define it too narrowly and you will defeat the objective. My experience suggests that no matter how wide we draw the boundary it will never be wide enough to capture all variation points : Outside Context Problems are always possible.
The case studies show that basically, generative programming means generic programming with templates and that DSLs are limited to configuration of these templates.
In conclusion, this book is worth reading because it has many fresh ideas which will stretch your thinking and reconsider some ideas. It also brings some new tools to the multi-paradigm approach which is a good thing. However, much of the material is too academic for day to day use, both in the approach of the authors and in the applicability of some ideas.
Trends
By Reg. Charney
Last month I talked about all the trends being in lock step. This month seems to continue that trend. However, the most pressing problem is: “Will the downward trend grow worse or not?”
Figure #1 shows the normalized job demand for IT skills and demand for software engineers both in the U.S., in general, and in Silicon Valley, in particular. Notice that the decrease of job openings has leveled off over the last six months.
Figure #2 shows the absolute change in the normalized number of job. That is, it shows that the rate of change of job openings has stabilized. The radical changes in job openings has cycled down to the point where the rate of job openings is almost zero.
Because of the lack of change, there is little to report. This is in stark contrast to all the headlines we have seen in the last few months proclaiming all sorts of layoffs. Since the trends we have been plotting have usually preceded major changes by about a month, these trend lines indicate that the layoffs have had no real or immediate impact on the IT job market.
That said, we are now running at about 1/3 the job openings that we did at the beginning of last year.
Top technologies
Recently, the top technologies (highest to lowest) requested in job postings are:
ASP
Web
TCP/IP
Object-Oriented
Design
COM
Figure #3 shows that the most dramatic changes in technology demand is in the areas of database and ASIC skills. This falloff in the skills listed is consistent with the problems that internet companies and chip manufacturers are having at the moment. However, there is still a growing demand for ASP and client/server software skills.
Thanks to DICE at www.dice.com for a truly valuable service and allowing me to analyze some of their data.