• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1+++
2title = "Error codes"
3description = "Error codes with their good and bad sides."
4weight = 30
5+++
6
7
8Error codes are reasonable error handling technique, also working in C.
9In this case the information is also stored as an `int`, but returned by value,
10which makes it possible to make functions pure (side-effect-free and referentially
11transparent).
12
13```c++
14int readInt(const char * filename, int& val)
15{
16  FILE* fd;
17  int r = openFile(filename, /*out*/ fd);
18  if (r != 0)
19    return r; // return whatever error openFile() returned
20
21  r = readInt(fd, /*out*/ val);
22  if (r != 0)
23    return READERRC_NOINT; // my error code
24
25  return 0;   // success
26}
27```
28
29Because the type of the error information (`int`) is known statically, no memory
30allocation or type erasure is required. This technique is very efficient.
31
32
33### Downsides
34
35All failure paths written manually can be considered both an advantage and a
36disadvantage. Forgetting to put a failure handling `if` causes bugs.
37
38If I need to substitute an error code returned by lower-level function with mine
39more appropriate at this level, the information about the original failure is
40gone.
41
42Also, all possible error codes invented by different programmers in different
43third party libraries must fit into one `int` and not overlap with any other error
44code value. This is quite impossible and does not scale well.
45
46Because errors are communicated through returned values, we cannot use function's
47return type to return computed values. Computed values are written to function
48*output* parameters, which requires objects to be created before we have values
49to put into them. This requires many objects in unintended state to exist. Writing
50to output parameters often requires an indirection and can incur some run-time cost.
51