This is an old revision of the document!
handling enum
s in C++ is tricky. but there are good practices that can help you out. here are two from the set.
let's say we have a simple enum
called Foo
, with some values. we want to add a str()
helper, that would covert it to sth more human-readable than a number. very common implementation would be:
enum class Foo { A, B, C }; // ... auto str(Foo f) { switch(f) { case Foo::A: return "A"; case Foo::B: return "B"; case Foo::C: return "C"; default: return "<unknown>"; } }
looks good, all tests pass. however there is a potential for a problem – it's not future proof. let's now add Foo::D
:
enum class Foo { A, B, C, D }; // notice Foo::D is added! // ... auto str(Foo f) { switch(f) { case Foo::A: return "A"; case Foo::B: return "B"; case Foo::C: return "C"; default: return "<unknown>"; } }
looks good, all tests pass… however now there _is_ a problem! new value is not handled and it will return an incorrect value at runtime!
there's a neat way of fixing this problem and making code future-proof. compile with -Wall -Werror
(as you anyway should!) and make sure no switch
has any default
. eg.:
auto str(Foo f) { switch(f) { case Foo::A: return "A"; case Foo::B: return "B"; case Foo::C: return "C"; } return "<unknown>"; }
change looks insignificant, but now if we miss handling 1 value, we get a warning from a compiler and with -Werror
it stops the build right away.
c.cpp: In function ‘auto str(Foo)’: c.cpp:11:9: error: enumeration value ‘D’ not handled in switch [-Werror=switch] 11 | switch(f) | ^ cc1plus: all warnings being treated as errors
bug is detected at compile time! nice… :)