If something can be nil, handle the case. There’s nothing brilliant about objective-C’s nil kludge.
If something can be nil, handle the case. There’s nothing brilliant about objective-C’s nil kludge.
Yes, you need to know what you're doing in any language, the difference is whether those things are due to the language or the problem you're actually trying to solve. The more things in the language you have to keep in mind, the less of your domain problems you have room for.
I'd rather take a crash (that way I'll know soon that I have a bug and it'll be easy to fix) or, even better, a compiler/type error ("code is expecting a fully constructed object but doesn't always receive one").
In C++ I recently started using a NonNull<> templated type (with specializations for std::unique_ptr<> and std::shared_ptr<>): https://github.com/alefore/edge/blob/af1192a70646f662539bfe6...
It's slightly verbose, but has allowed me to delete a ton of CHECK(x != nullptr) statements (since the type will already carry the information that x can't be null) and this use of types has helped me detect a few mismatches (where e.g. the consumer had unnecessary complexity to deal with null but the caller always emitted fully constructed types, or the, much worse, symmetric case).
What does bother me is where you detect the bug.
Is it at compile-time?
Is it at run-time through a crash?
or is it months later after you notice that many of your users seem to have January 1st 1970 as their birthday with no way of recovering the lost data.
But hey - at least stuff kept running. Right?
This year has already seen CVE-2022-25636 (heap out-of-bounds write), CVE-2022-27666 (buffer overflow), and CVE-2922-0847 (uninitialised memory). Three vulnerabilities in the Linux kernel, in pretty important (and therefore, presumably, closely scrutinised) bits of the code base. And this is the Linux kernel, arguably the most important open source project in the world, worked on by some of the most skilled developers out there.
Everybody writes bad code, and everybody misses bad code on review, even in the really important bits, even when they’re well-known bug classes. Criticising a language for leaving these foot guns lying about is perfectly reasonable, and it’s important we talk about avoiding those languages wherever possible.
Other times, the need to have direct hardware access from the BIOS on up cannot be avoided.
The bugaboo is the quest for the One True System that is all things to all people.
Emacs is as close as we get to that Nirvana.
The correct reasoning would be to recognize that certain language features make entire classes of bugs impossible. For example, in my Rust projects, I never have to worry about null pointer errors. Sure, there might be other types of bugs in my code. But at least I don't have bugs due to nulls. Also, there are no data races in my code—yet another thing I don't have to worry about thanks to the design of the language. (I'm not saying Rust is perfect. I'm just using it as an example.)