"proven" sounds like cargo-culting dogma. The same was said of OOP in the 90s, and look what that caused. Hence my distrust of the snake-oil.
Also, my real-world experience with wading through the abstraction insanity often seen in C++ (and justified because it's "safer") to find and fix bugs, and even more so with the sheer baroqueness of Enterprise Java (arguably an "even safer language"), shows that "reduce defects" is more like a dream. Maybe the number is reduced but when one is found, it tends to be harder to fix.
Put another way, I'd rather fix relatively simple C (which also tends to be simpler code in general) than the monsters created by "modern C++" because they thought the "added safety" would mean they could go crazy with the complexity without adding bugs. Perhaps there is some sort of risk compensation going on.
The saying "C makes it easy to shoot yourself in the foot; C++ makes it easy to blow the whole leg off" comes to mind.
> Put another way, I'd rather fix relatively simple C (which also tends to be simpler code in general) than the monsters created by "modern C++" because they thought the "added safety" would mean they could go crazy with the complexity without adding bugs.
It's completely possible to write C++ code without it being a mess of a template mostrosity and massively overloaded function names. People who write C++ like that would write C filled with macros, void pointers and all the other footguns that C encourages you to use instead.
I've been working with the sentry-native SDK recently [0] which is a C api. It's full of macros, unclear ownership of pointers (in their callback, _you_ must manually free the random pointer, using the right free method for their type, which isn't type checked), custom functions for working with their types (sentry_free, sentry_free_envelope), opaque data types (everythign is a sentry_value_t created by a custom function - to access the data you have to call the right function not just access the member, and this is a runtime check).
See [1] (their C api example). With function overloading and class methods it would be much more readable.
There's a bug difference between extremely complex c++ templates and std::unique_ptr, std::string_view, and constexpr. Also, I've heard many game devs still saying unit tests either take too long to write or they aren't helpful.
I think that if we focused on building small, simple programs that do one thing well and compose, C would be OK. It’s when we build out behemoths that you really have a hard time reasoning about your code. At that point, vulnerabilities are almost guaranteed. This is true in any language, but more so in unsafe ones.
The complexity that must arise (otherwise the problem we are looking at is not interesting enough) will happen either way. Composing small tools will give you an ugly as hell glue code over them — just imagine a modern browser. Would it really be better to do curl and interpretJS and buildDOM and all these things? Just imagine writing the glue code for that in what, bash?
We pretty much have exactly that, but better with programming languages composing libs, functions and other abstractions. That’s exactly the same thing but at a different (better) level.
Also, my real-world experience with wading through the abstraction insanity often seen in C++ (and justified because it's "safer") to find and fix bugs, and even more so with the sheer baroqueness of Enterprise Java (arguably an "even safer language"), shows that "reduce defects" is more like a dream. Maybe the number is reduced but when one is found, it tends to be harder to fix.
Put another way, I'd rather fix relatively simple C (which also tends to be simpler code in general) than the monsters created by "modern C++" because they thought the "added safety" would mean they could go crazy with the complexity without adding bugs. Perhaps there is some sort of risk compensation going on.
The saying "C makes it easy to shoot yourself in the foot; C++ makes it easy to blow the whole leg off" comes to mind.