In C ++, enums are unsafe. You cannot expect the enumeration value to be one of the values โโdefined in the enumeration declaration:
- it can be uninitialized (thus garbage)
- you may have the wrong
static_cast from int
Therefore, the compiler cannot wait for the switch to return, even if you cover all the elements of your enumeration. However, this is indeed a condition of error, functionally speaking.
There are two ways of reaction:
- add
default to your enum - add instructions after switching
To choose the right one, remember that the compiler can (if you ask it) raise a warning whenever the switch does not cover all cases of enum provided that there is no default expression. Intelligent compilers (for example, Clang) allow you to correlate warnings with errors individually, which helps to catch these errors.
Therefore, you have a decision to accept:
- if you want to be notified when you forget to change this method after updating the listing, then do not use
default - if you want to update the enumeration and ignore this switch, use
default
Finally, you need to decide how to respond, noting that using a runtime error is incompatible with the default instruction (it is best to catch errors at compile time when possible):
- ignore the error and return some predefined value
- throw an exception (indicating the value of the listing, please)
- assert (and thus crashing in debugging, getting a memory dump and doing something else in the release, like nothing or an exception)
My personal fav is a UNREACHABLE(Text_) macro UNREACHABLE(Text_) , which causes a memory dump in Debug (so that I get a full trace) and logs an error and throws Release (so that the server stops processing this request but does not stop responding at all).
This gives the following code:
char const* func(ENUM x) { switch(x) { case Option1: return "Option1"; case Option2: return "Option2"; case Option3: return "Option3"; } UNREACHABLE("func(ENUM)") }
source share