ledow wrote: ↑
Fri May 24, 2019 12:50 pm
NULL checks are critical and should be absolutely everywhere. And result in instant failure of the application, with full debugging trace.
The first line of any new C function that I write is literally just a list of any pointer parameters with:
assert(parameter != NULL);
assert(parameter2 != NULL);
Honestly if you have to do this then the wrong language is being used. In C++ document that a passed in value will never be null by taking it as a reference instead of a naked pointer. Or better yet, use an ownership type to enforce it by checking constraints at compile-time instead of run-time (thus converting to the owned type would force a runtime check, but all things considered everything should be created in an owned state so no checks should never need to be performed at all). This is trivial in C++ and is, honestly, the main reason to use C++ (a pox on classes). C++'s type system is significantly stronger than C's and by using it you get more succinct code, better documented code, *faster* code, and most importantly, much harder for you yourself to break it when you 'maintain' it sometime in the future.
Rust's ownership system takes the standard C++ ownership style and bakes it into the language itself, so any aspiring programmers I'd highly recommend learning rust. Even if you don't "use" rust (which honestly you should use rust) learning that ownership model will help you when programming in any other language.
Checking null on pointers that should never ever be null just means your checks are in the wrong place and your type system is weak, you can and should do better for a variety of reasons.
On an aside, the two errors mentioned in that article would not have happened with Rust or in a well typed C++ setup (there are some fantastic libraries out for that).
Omnifarious wrote: ↑
Fri May 24, 2019 1:27 pm
I rarely trust myself to generate test cases that truly exercise all the code paths or combinations thereof, and so I write a test that generates significant swaths of the possible input space and tests all of them. Even then I've sometimes missed things.
You might be interested in property check testing systems then. Quickcheck is the most popular.
Even then, both of these bugs would not have even needed to be tested for with better types in their codebase as they just would have been categorically impossible, nor are they something most humans would even think to check for as they are 'impossible cases'. If a case should be impossible then make it so via using proper types.
Rakshasa wrote: ↑
Fri May 24, 2019 1:20 pm
The point of 'assert' is that you can compile it with NDEBUG defined to disable it when making a release build, thus allowing you to have as many asserts as you want while working on the code without affecting production code.
This is also a very bad use of assert. Either enforce that the argument cannot be `nullptr` via proper Types, or always perform an explicit test if it is otherwise possible. Don't do this wishy-washy stuff, it just makes it hard to maintain in the future, adds needless cognitive load, etc...