In Monday’s post, “Out-of-Band Error Reporting Without Exceptions”, I described a method for elegantly obtaining three out of five major advantages of C++ exceptions without actually using them. Now I’ll tell you how to go about grabbing a fourth advantage: exception type hierarchies.
C++ exceptions are hierarchical, and their hierarchy is a type hierarchy such that a more-derived exception can be treated, if desired, as one of its base exception types. For example, a FileNotFoundException might be derived from FileIOException. Some code may choose to handle FileNotFoundExceptions distinctly from other FileIOExceptions. Other code might delegate all FileIOExceptions to a common handler. In C++ this is done with implicit typecasting in the catch statements in a try block.
Wouldn’t it be useful if we could do something similar with the ErrorReport and CheckedValue classes that were defined in Monday’s post, instead of just having an error/not-an-error indicator and a human-readable message? Well, we can. It’s easy to use but a little tricky to set up.
(more…)
The newest article in my series on the Lottery Problem describes the design decisions I made when making my first attempt at an implementation of an efficient wheel generator based on the simple greedy algorithm for set cover. The design decisions described were influenced by three key insights I had when considering how one might attempt to generate a close-to-optimal wheel for a 6-from-49 lottery in a reasonable amount of time.
- Once the relationships between tickets have been completely expressed, the actual numbers that constitute the tickets are of no significance and can be discarded.
- It is only necessary to keep track of how many uncovered tickets an unselected ticket could potentially cover if selected. It is unnecessary to know exactly which tickets those are.
- Every ticket initially covers the same number of other tickets, and this number can be computed through combinatorics alone.
You can read the full article here. It primarily addresses the challenges involved in expressing the problem within a reasonable amount of memory, and gives an overview of how the computation will be approached. The computation itself will be described in detail in the next article.
Let’s say, for the sake of argument, that you’re working in C++ and you happen to be in an environment where exceptions don’t work. In my case, it was an embedded environment where the miniaturized C++ standard library didn’t support them, but in your case it may be that you can’t use them for performance reasons, or they’re against policy or something else.
As opposed to the old C-style return codes, C++ exceptions offer five major advantages:
- They are out of band (that is, a function returning an integer need not assign a special value, e.g. -1, to mean “error”).
- They can carry information about the specific error that occurred, as opposed to simply a code with a general meaning.
- They exist in a type hierarchy. A
FileNotFoundException may be derived from a FileIOException, and a handler for the latter can handle the former.
- If you ignore them, your program blows up. This is a good thing – an undetected error is far worse than a fatal error.
- They automatically unwind the stack to find a handler.
And these are all reasons why, unless you have a good reason not to, you should prefer using exceptions. But in the case when you can’t, it turns out that point 5 is really the only advantage that you have to do without. There’s a relatively elegant method that you can use to achive the first four advantages without using exceptions at all.
(more…)