5 ms·
> All if, else if constructs will contain either a final else clause or a comment indicating why a final else clause is not necessary. I actually do this as we
by don-code 10mo ago
> All if, else if constructs will contain either a final else clause or a comment indicating why a final else clause is not necessary.
I actually do this as well, but in addition I log out a message like, "value was neither found nor not found. This should never happen."
This is incredibly useful for debugging. When code is running at scale, nonzero probability events happen all the time, and being able to immediately understand what happened - even if I don't understand why - has been very valuable to me.
- torben-friis 10mo agoI like rust matching for this reason: You need to cover all branches. In fact, not using a default (the else clause equivalent) is ideal if you can explicitly cover all cases, because then if the possibilities expand (say a new value in an enum) you’ll be annoyed by the compiler to cover the new case, which might otherwise slip by.
- uecker 10mo agoAnd I like using enums in C ;-) The compiler tells you to cover all branches. https://godbolt.org/z/bY1P9Kx7n https://godbolt.org/z/bY1P9Kx7n
- rundev 10mo agoThe compiler also tells you that even if you cover all enum members, you still need a `default` to cover everything, because C enums allow non-member values.
- torben-friis 10mo agoRust is a bit smarter than that, in that it covers exhaustiveness of possible states, for more than just enums: fn g(x: u8) { match x { 0..=10 => {}, 20..=200 => {}, } } That for example would complain about the ranges 11 to 19 and 201 to 255 not being covered. You could try to map ranges to enum values, but then nobody would guarantee that you covered the whole range while mapping to enums so you’d be moving the problem to a different location. Rust approach is not flawless, larger data types like i32 or floats can’t check full coverage (I suppose for performance reasons) but still quite useful.
- uecker 10mo agoIn principle C compilers can do this too https://godbolt.org/z/Ev4berx8d https://godbolt.org/z/Ev4berx8d although you need to trick them to do this for you. This could certainly be improved.
- YesBox 10mo agoSame. I go one step further and create a macro _STOP which is defined as w/e your language's DebugBreak() is. And if it's really important, _CRASH (this coerces me to fix the issue immediately)
- creato 10mo agoThe "standard" (typically defined in projects I'm familiar with, and as of C23, an actual standard) is "unreachable": https://en.cppreference.com/w/c/program/unreachable.html https://en.cppreference.com/w/c/program/unreachable.html
- YesBox 10mo agoC++ keeps getting bigger and bigger :D Thanks for sharing
- creato 10mo agoThis is actually C and C++ has not done something similar AFAIK.
- hn_go_brrrrr 10mo agoFortunately the major compiler vendors all have. Routing around the standards committee is getting more and more common.
- Fulgen 10mo agohttps://en.cppreference.com/w/cpp/utility/unreachable.html https://en.cppreference.com/w/cpp/utility/unreachable.html
- TuxSH 10mo agoC++23 does have std::unreachable (as a function), and its counterpart [[assume(expr)]]
- vlovich123 10mo ago