Two weeks ago I’ve blogged about using C++’s type system to prevent errors. The post spawned a lot of discussion so I wanted to address some of the responses I’ve got. I’ve also said at the end of the post that I was going to write a library that helps to implement the techniques. The library is now done - type_safe can be found on Github, but please do read on for a discussion about the motivation and feature overview.» read more »
In the previous part of the error handling series I’ve talked about assertions and wrote a debug assert library that provides flexible assertions.
Assertions are a useful tool to check preconditions of functions - but proper type design can prevent situations where assertions are needed. C++ has a great type system, let’s use it to our advantage.
At the recent CppCon Ben Deane gave a - as far as I’ve heard - great talk about type design. I sadly didn’t attend the conference and his video isn’t released yet but according to the slides there is some overlapping between his talk and what I’m going to say. But because I’ve planned this posts for weeks and even made the entire series just for it I decided to post it anyway. After all: some things cannot be said often enough.
» read more »
Also I’m going to focus explicitly about type design for error handling, while his talk seems to be more generic.
In part 1 of the series I’ve talked about various error handling strategies and when to use which one. In particular, I said that function precondition should only be checked with debug assertions, i.e. only in debug mode.
The C library provides the macro
assert() for checking a condition only if
NDEBUG is not defined.
But as with most things coming from C, it is a simple but sometimes not sufficient solution.
The biggest problem I have with it is that it is global, you either have assertions everywhere or none.
This is bad, because you might not want to have assertions enabled in a library, only in your own code.
For that reason, many library programmers write an assertion macro themselves, over and over again.
Instead, let’s write same thing better ourselves, but something we can easily reuse.» read more »
There is the concept TS, a technical specification for including concepts into C++17. Concepts have always been a … concept in C++. They are used to document constraints on template parameters. For example:
template <typename RandomAccessIterator, typename Comperator> void sort(RandomAccessIterator begin, RandomAccessIterator end, Comperator comp);
This function has the requirement that
end are both random access iterators and
comp is a comparison function.
Right now, the concepts are only documented and ignoring them leads to great error messages.
The concept TS provides ways to embed them in the language directly and make, for example, overloading based on the concept easier.
But it doesn’t really bring anything new to the language. Everything it does can be accomplished with C++11’s expression SFINAE today, it only brings an (arguably) cleaner syntax and more complexity to the language.
In this post I’ll show you how to do implement concepts using only C++14 language features. I’ll try to make it as easy as possible by introducing some library utilities you can use very easily.» read more »
To quote a previous post: “Sometimes things aren’t working.” If something isn’t working, you have to deal with it. But how?
There are two fundamental kinds of strategies:
recoverable error handling (exceptions, error return codes, handler functions) and un-recoverable error handling (
When do I use which one?