Expected
And I say to any creature who may be listening, there can be no justice so long as laws are absolute. Even life itself is an exercise in exceptions.
— Captain Jean-Luc Picard
This tutorial is optional, in the sense that it does not talk about Windows programming per se. Error handling is an important topic, though, thus, please don’t disregard it completely. If you are on the fast track to get your first window up and running, however, it will be enough to understand how to use the Expected idea introduced in this tutorial; or at least to understand it well enough to be able to read the source code of the tutorials.
Exceptions
The C++ programming language provides built-in support for throwing and catching exceptions if something goes wrong at runtime, by offering the try, throw, and catch expressions.
Here is a silly example:
First, a try-block is used to enclose the statement that might throw an exception. The test function signals that an
exceptional condition, often, an error, occurred, by throwing an exception. C++ offers a few standard exceptions to
throw, which are listed here. In this case, an invalid argument
exception is thrown when the test function is fed with the number
To handle exceptions that may be thrown, catch-blocks are implemented immediately following a try-block. In this
example, WinMain simply exits with return value
It is possible to use an object of any type as the operand of a throw expression, in most cases it is easiest to use the std::exception or one of its derived classes. However, if those are not appropriate enough, it is possible to derive a custom exception class from std::exception.
For more information about exception handling, check the appropriate page on the MSDN.
There are a few problems with exceptions though: most importantly for games, exceptions are really slow. In most C++ implementations the code in a try-block runs as fast as it normally would, however, a catch-block is orders of magnitude slower: The runtime increases linearly with the depth of the call-stack.
Exceptions are also hopelessly serial and do not allow storing of error messages to be handled at a later moment.
Expected
To overcome these limitions, Dr. Andrei Alexandrescu proposes the
Expected
The key idea is that Expected
Here is the class based on the above talk:
And here is a variation of the example from above:
So the basic idea behind the Expected-idiom is that each function has an expected return value (an int, a class, void, …). Thus, if the function call succeeds, the return value is stored in an instance of the Expected class. If something goes wrong however, the actual error is stored in the same instance of the Expected class. After having called a function, it is very easy to simply check whether we got the expected return value or an error.
In this example, the function returns an empty Expected (as it was supposed to return void) if everything went well,
but if it sees the number
You can download the source code for the above example from here.
In conclusion: Error handling with Expected is a lot more powerful than standard exceptions and in addition, it makes the code a lot easier to read. Everything flows more naturally.
References
(in alphabetic order)
- Microsoft Developer Network (MSDN)
- Systematic Error Handling in C++, by Dr. Andrei Alexandrescu