void foo(T& out) - How to fix output parameters

There are some cases where you need to return a value from a function but cannot use the return value. It happens, for example, in functions where you want to return multiple values at once. While you can pass multiple inputs to a function - the parameters, you cannot pass multiple return values in the same way.

C++ programmers tend to use a good old (lvalue) reference for that. You take a non-const reference as parameter and assign the output to that reference. The caller will pass a variable and upon function completion find the value of the variable changed.

Yet this approach has some problems: For starters, it is not obvious when just looking at the call that the variable is going to be changed. This is the reason that C++ style guides such as the one used by Google recommend using a pointer for that. The caller then has to explicitly pass in the address of the variable, making it explicit.

But with a pointer you can now pass in nullptr, you have to check for that in the function: A pointer where you really mean “reference” does not follow the guidelines I’ve been advocating for.

So is there not a universal solution?

There is, but first we need to understand the full scope of the problem.

» read more »
Jonathan

Tutorial: Emulating strong/opaque typedefs in C++

Last week, I’ve released my type_safe library. I described it’s features in the corresponding blog post but because the blog post got rather long, I couldn’t cover one feature: strong typedefs.

Strong or opaque typedefs are a very powerful feature if you want to prevent errors with the type system – and as I’ve been advocating for, you want that. Unlike “normal” typedefs, they are a true type definition: they create a new type and allow stuff like overloading on them and/or prevent implicit conversions.

Sadly, C++ doesn’t provide a native way to create them, so you have to resort to a library based emulation.

BTW, type_safe received a couple of requested features: There are improvements to the monadic optional functions (bind(), map(), unwrap() as well as a new transform()), multi-visitation of optionals and ArithmeticPolicy to control over/underflow behavior of the ts::integer<T>.

» read more »
Jonathan

Type safe - Zero overhead utilities for more type safety

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 »
Jonathan

Prevent precondition errors with the C++ type system

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.

Also I’m going to focus explicitly about type design for error handling, while his talk seems to be more generic.

» read more »
Jonathan

How do I implement assertions?

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 »
Jonathan