Skip to content

Implemented a hint for optimizers to better detect unreachable code

Summary

I've added the macros DUNE_UNREACHABLE and DUNE_UNREACHABLE_MSG that wrap some compiler builtin functionality to mark code segments as unreachable.

Motivation

This might be useful to optimize switch-case statements over the values of an enum, where all enumeration values are handled. The compiler does not necessarily recognize this and implements additional checks and branches.

Also, the macro can be used to suppress compiler warnings about missing return statements in non-void functions, e.g.

int foo() {
  switch (flag) {
    case f1: return 1;
    case f2: return 2;
  }
}

If flag in the example can only have the two values f1 or f2 all cases are handled, but the compiler throws the warning of a missing return statement, since there is not default: case. But what to return on default? A std::abort() could be fine, but the most optimal code is produced when the default: case is marked unreachable. At least in clang >= 3.7 and gcc >= 8:

int foo() {
  switch (flag) {
    case f1: return 1;
    case f2: return 2;
    default: DUNE_UNREACHABLE;
  }
}

Discussion

The macro is implemented so that in the unexpected case that the unreachable line is reached, the DUNE_THROW is called, except if -DNDEBUG is set. It maybe discussed, whether a std::abort() call is better than an exception in the debug case.

A reached unreachable line causes undefined behaviour. Thus, the macro should be used only in cases where you are sure that this does not happen. The critical line can be found in debug mode, since an error is thrown, or (in case of unhandled enum values) by adding the warning flag -Wswitch-enum.

Edited by Simon Praetorius

Merge request reports

Loading