6 ms·
> This seems like a bad idea, because the whole point of an assert is that something shouldn't happen, but might due to a (future?) bug. And so it’s a bad idea
by haimez 3y ago
> This seems like a bad idea, because the whole point of an assert is that something shouldn't happen, but might due to a (future?) bug.
And so it’s a bad idea because…?
The whole idea is to notice a bug before it ships. Asserts are usually enabled in test and debug builds. So having an assert hit the “unreachable” path should be a good way to notice “hey, you’ve achieved the unexpected” in a bad way. You’re going to need to clarify in more detail why you think that’s a bad thing. I’m guessing because you would prefer this to be a real runtime check in non debug builds?
- im3w1l 3y agoIt's undefined behavior if the assert triggers in production. It's too greedy for minor performance benefit at the risk of causing strange issues.
- haimez 3y agoYikes. I did have to go down a little rabbit hole to understand the semantics of that builtin (I don’t normally write C if that wasn’t immediately obvious from the question) but that seems like a really questionable interpretation of “this should never happen”. I would expect the equivalent of a fault being triggered and termination of the program, but I guess this is what the legacy of intentionally obtuse undefined behavior handling in compilers gets you.
- im3w1l 3y agoThe builtin itself is fine. It works exactly as it's intended. It says "I've double and tripple checked this. Trust me compiler. Just go fast". But you should not use it to construct an assert.
- LoganDark 3y agothis is a true unconditional assert, e.g. "I assert that this condition is true". Problem is that's too much power to throw at most use cases.
- josephg 3y agoEh. I absolutely get what you're saying. And this is for sure flying very close to the knife's edge. But if your assertion checks don't run in release mode, and due to some bug, those invariants don't hold, well, your program is already going to exhibit undefined behaviour. Why not let the compiler know about the undefined behaviour so it can optimize better? The nice thing about this approach is that the assertion provides value both in debug and release mode. In debug mode, it checks your invariants. And in release mode, it makes your program smaller and faster. Personally I quite like rust's choice to have a pair of assert functions: assert!() and debug_assert!(). The standard assert function still does its check in both debug and release mode. And honestly thats a fine default these days. Sure, it makes the binary slightly bigger and the program slightly slower, but on modern computers it usually doesn't matter. And when it does matter (like your assertion check is expensive), we have debug_assert instead.
- dxhdr 3y ago> But if your assertion checks don't run in release mode, and due to some bug, those invariants don't hold, well, your program is already going to exhibit undefined behaviour. Why not let the compiler know about the undefined behaviour so it can optimize better? Usually in release mode you want to log the core dump and then fix the bug.
- josephg 3y agoYeah; thats why I like rust's approach. You can either leave assertions in in release mode, so you get your core dump. Or you can take them out if you're confident they won't fire in order to make the program faster. The unreachable pragma suggested by the author is just a more extreme version of the latter choice.