3 ms·
As a side note, this article suggests using assert. Fine, but make sure you know what your assert does, and when it does that, if you have a debug and release b
by uxp100 6y ago
As a side note, this article suggests using assert. Fine, but make sure you know what your assert does, and when it does that, if you have a debug and release build (which I think you probably shouldn't.)
I've spent some time with "offensive" programming in the context of both security (like key leakage) and safety (like firmware integrity). It was just kinda funny thinking about meetings spent determining what we could do if i2c or something wasn't responding, and different approaches to try and fix it, and then a year later going back and saying, ok, if something isn't working, we've got an easy answer. Lockdown and halt boot. Anything seems weird, just stop trying.
- iso8859-1 6y agoRuntime assertions are easily inserted, but why not change the types, make that case impossible? Dependent types can make that happen. Static assertions are enabled by dependent typing. But unlike dependent typing, static assertions are only assertions, for example they do not enable you to write a function that returns different types based on its arguments. Static assertions do not allow you to write a compile-time vector type.
- AnimalMuppet 6y ago"Making that case impossible" is hard for i2c not responding. You can represent "not responding" in a way that isn't confused with real data (even if zero-length), and you can refuse to go down the path that expects data. But no dependent type can make it respond. And you're still stuck with the questions: "What do I do then? How do I handle it? Can my program continue at all? How do I tell the user what's wrong?" As far as I can see, dependent types don't help with the larger problem at all.
- lmm 6y agoTypes (you don't even need full dependent types) let you check your reasoning about why something is true, which is IME the core of the larger problem. Most of the time the bug doesn't happen because everyone forgot that it's possible for i2c to not respond, it's because component a thought that it should pass the i2c response straight through to component b and component b would handle the i2c not responding, whereas component b thought that component a had already handled the case where the i2c didn't respond (or rather, component b is a pass-through middleware that calls component c that wraps component d and component d thought that i2c not responding had already been handled). Types absolutely help with that.
- hansvm 6y agoPlausibly, there could be plenty of cases for favoring runtime assertions over dependent types. Or for mixing and matching even in cases where one or the other would probably suffice. - Dependent types aren't easily available everywhere. If you don't have them then you can't use them. - The compiler can't prove some statements (admittedly not a big issue for the examples from TFA). Supposing you have a dependent type system which allows you to state that a property holds, it could still be prudent to have a runtime check. If the type system doesn't allow such statements then it isn't sufficiently expressive to solve the problem in the first place. - Assertions are a local change which one can make incrementally, whereas changing the types being used will immediately require larger changes (if the types are used more than once) or necessitate some extra wrapper code.
- greatgib 6y agoIt's easy and a lot of manufacturer do the 'unexpected circonstances? Stop and reboots. But it is really nocive in the context of real products. This is how you finish with the samsung blu ray player that became suddenly a brick. Unusable and unupdatable to be fixed. Also, there used to be a lot of Android phone that became unusable bricks because they were stuck in boot loops and nothing could be done to go to a recovery or update stage. That case was common for example when there was a few corrupted or dead bits in internal ram or storage.
- hansvm 6y agoThere are _still_ android phones that become unusable bricks because they're stuck in boot loops. Google will happily send you another new phone, but the 4XL is vulnerable to one of the recent updates.
- astrobe_ 6y agoYes, it can be really counter-productive if done wrong. You have to do everything possible to reach a stage where a firmware update is possible. Only after that you can kick the reset line when you're unhappy.
- karlding 6y ago> make sure you know what your assert does, and when it does that, if you have a debug and release build Absolutely. Probably the most common difference I've seen in "Debug" and "Release" builds relying on the standard library headers is when NDEBUG is defined as a macro when <assert.h> is included, which causes assert to become a no-op [0]. This has interesting implications when developers accidentally rely on the side effects of functions and assert on the return value of that helper. On "Release" builds that side effect would be compiled out. For that case, clang-tidy has the bugprone-assert-side-effect [1] checker if you want to enforce this in your CI. [0] https://en.cppreference.com/w/c/error/assert https://en.cppreference.com/w/c/error/assert [1] https://clang.llvm.org/extra/clang-tidy/checks/bugprone-assert-side-effect.html https://clang.llvm.org/extra/clang-tidy/checks/bugprone-asse...