Differences

This shows you the differences between two versions of the page.

Link to this comparison view

blog:2023:08:26:2023-08-26_-_handling_enums_in_c [2023/08/26 15:43] – created baszblog:2023:08:26:2023-08-26_-_handling_enums_in_c [2023/08/26 15:50] (current) – tips and tricks on handlign enums in C++ basz
Line 73: Line 73:
  
 ===== handling some values ===== ===== handling some values =====
 +
 +another common case where ''enum''s are used is adding special functions, that check if value is in a given logical state / group. eg. determining if it's an error:
 +
 +<code cpp>
 +enum class State
 +{
 +  Initializing,
 +  Running,
 +  InputError
 +};
 +
 +bool isOk(State s)
 +{
 +  return s != State::InputError;
 +}
 +</code>
 +
 +looks good, all tests pass. however... you probably already know where it's going. ;) let's consider extending ''State'' with a new error state:
 +
 +
 +<code cpp>
 +enum class State
 +{
 +  Initializing,
 +  Running,
 +  InputError,
 +  OutputError
 +};
 +</code>
 +
 +...and now ''isOk(State::OutputError) == true''. whoops...
 +
 +a better way of writing these kind of function is to list all ''enum'' values explicitly, and assign ''return''s accordingly, eg.:
 +
 +<code cpp>
 +#include <cassert>
 +// ...
 +bool isOk(State s)
 +{
 +  switch(s)
 +  {
 +    case State::Initializing:
 +    case State::Running:
 +      return true;
 +    case State::InputError:
 +      return false;
 +  }
 +  assert(!"unknown value");
 +}
 +</code>
 +
 +now, if states change, we get a proper error:
 +
 +  4.cpp: In function ‘bool isOk(State)’:
 +  4.cpp:13:9: error: enumeration value ‘OutputError’ not handled in switch [-Werror=switch]
 +     13 |   switch(s)
 +        |         ^
 +  cc1plus: all warnings being treated as errors
 +
 +so we know we need to fix it:
 +
 +<code cpp>
 +#include <cassert>
 +// ...
 +bool isOk(State s)
 +{
 +  switch(s)
 +  {
 +    case State::Initializing:
 +    case State::Running:
 +      return true;
 +    case State::InputError:
 +    case State::OutputError:
 +      return false;
 +  }
 +  assert(!"unknown value");
 +}
 +</code>
 +
 +while writing this kind of functions using ''switch''-''case'' may look a bit odd at first, it has a very nice property of ensuring code being future-proof. as a side effect, it also makes core far easier to read. for comparison just imagine ''isOk()'' where there are 7 "ok" states and 13 "error" states...
blog/2023/08/26/2023-08-26_-_handling_enums_in_c.txt · Last modified: 2023/08/26 15:50 by basz
Back to top
Valid CSS Driven by DokuWiki Recent changes RSS feed Valid XHTML 1.0