To me this idea sounds a lot like "why do we need IPV6? Why not keep IPV4 and add a few bytes?" except it's effectively almost the same amount of breakage. Either you're C-compatible or you're not.
Making C memory-safe by adding extra annotations to allow for static zoning/borrow checking is possible, but the churn involved is probably not much different than rewriting in a different language. See Cyclone for instance if you want to see what such an approach looks like.
On top of that modern languages have facilities that are seriously lacking from C, memory safe or not. C's error handling is atrocious, C doesn't have (standard) destructors, C doesn't have type inference, C doesn't have algebraic types, C doesn't have proper string/collection support etc...
I like C quite a lot, it's probably the language I know best, but it's definitely very outdated. I think in the not so far future it'll be almost entirely replaced outside of legacy applications, hopefully with Rust. I think the watershed moment will be when the Linux kernel is rewritten in an other language, which definitely won't happen overnight but at this point I'm fairly certain that it will happen within a couple of decades.
> To me this idea sounds a lot like "why do we need IPV6? Why not keep IPV4 and add a few bytes?" except it's effectively almost the same amount of breakage.
>The IPv6 designers made a fundamental conceptual mistake: they designed the IPv6 address space as an alternative to the IPv4 address space, rather than an extension to the IPv4 address space.
> Either you're C-compatible or you're not.
If we take this black and white approach then we must say that C++ is not C compatible just like Ada isn't C compatible.
The reality is that C++ being broadly a superset of C was integral to its adoption, even though that compatibility isn't perfect. It enabled easy incremental porting of projects.
This is really just a nit though. I do agree with your conclusions.
With all due respect I disagree with DJB here. I can't see how his proposal would significantly improve the current status quo. Note step one of his self-described "straightforward" transition plan (emphasis mine):
>0123456789abcdef0123456789abcdef to 192.5.6.30: The client sends a UDP packet to the .com DNS server asking for the address of www.google.com. The client software, intermediate computers, and server software have all been upgraded to handle the client's extended address.
A lot of work in this one "straightforward" step. I know that DJB is a great network engineer, so I'm willing to consider that I'm missing the point here, but at the very least I don't find this particular exposé very convincing.
>If we take this black and white approach then we must say that C++ is not C compatible just like Ada isn't C compatible.
Agreed, in a parent comment I mention C++ being effectively mostly compatible with C. But I can't really imagine how you could do something like that with a memory-safe subset of C. The changes involved are pretty thorough (you basically either need a garbage collector or a borrow checker). Things like raw pointers (especially nullable ones) can't really exist in their current form in a memory safe language.
The main strength of a memory-safe language is that the safety mechanisms are opt-out, not opt-in: you can confine the unsafe behavior to a small, manageable portion of the codebase. And trying to "fix" C to become a memory-safe language would probably just result in something like a Rust dialect that merely bears more superficial resemblance to C. In any case, thorough re-writing of existing codebases would be required. You might as well re-write in a language that currently exists, rather than add creating a new language to the top of the to-do list.
I would call C++ a memory safe language that has more than a superficial resemblance to C. Rust makes is more obvious when/where you are intentionally opting out, but most C++ memory bugs are where someone opted out of the modern C++ way to use the C way. (including new/delete as the C way).
This is a common viewpoint but also wrong. There's plenty of ways to invoke memory unsafety in 'modern' C++: iterator invalidation is probably the biggest source.
While you are technically correct, those who study C++ security note that those are a tiny minority of all security errors. Still an issue, but not nearly as common an issue as the ones that come from the C roots of C++.
Also can you link to an example of this purported memory safe C++ compiler? Please note for an apples to apples comparison it must reject all memory unsafe non-modern C++ constructs.
If C++ compilers had a default mode of rejecting code that was unsafe (any code using raw pointers or unchecked array access, I guess?), then sure- you could call it that. But as it is, no way.
In the same idea of "Any sufficiently complicated C program contains an ad hoc, bug-ridden, slow implementation of half of Common Lisp." let's paraphrase
Any sufficiently safe C program contains an ad-hoc (etc.) implementation of the infrastructure needed to make it safe:
- custom string implementation
- custom object/memory management
- custom memory slices and other data structures
Not forgetting the compiler tricks added to try and catch when the program does something stupid
FWIW, with my contrarian hat firmly affixed, I suspect that C plus tools makes more economic sense than Rust.
https://compcert.org/ > The CompCert project investigates the formal verification of realistic compilers usable for critical embedded software. Such verified compilers come with a mathematical, machine-checked proof that the generated executable code behaves exactly as prescribed by the semantics of the source program.
https://frama-c.com/ > Frama-C gathers several static and dynamic analysis techniques in a single collaborative framework. The collaborative approach of Frama-C allows static analyzers to build upon the results already computed by other analyzers in the framework.
https://www.cprover.org/cbmc/ > CBMC is a Bounded Model Checker for C and C++ programs. ... CBMC
verifies memory safety (which includes array bounds checks and checks for
the safe use of pointers), checks for exceptions, checks for various
variants of undefined behavior, and user-specified assertions.
I don't know how well that would work. For example, my understanding of Rust's bounding checking for slice indexing is that often the compiler can prove it's not needed and the check is optimised out because of the type system. This woulnd't work in C because of C's lacking type system
The people "in charge" of C are just not interested in radical changes - they have not even bothered to add better strings. There was a recent post here describing how the C standard bodies even oppose adding warnings, because it would increase the size of building logs.
So the only chance for advancement are those who propose radical changes, like Rust, or Zig if you want something less complex and "spiritually" closer to C
I based my comment on Jens Gustedt's article [1] about adding a "defer" mechanism in standard C.
Clearly, the C committee works hard on improving the language and they are in the process to standardize important features, such as lambda functions, auto, typeof (like C++'s decltype more or less), and so forth.
In my humble opinion, "defer" can mild the buffer / memory overflow, but of course not permanently remedied it 100%; to me though it's better to have such mechanism than have nothing at all to protect you.
Defer seems more like a solution to making cleanup easier and less error prone, preventing memory/fd/mutex leaks. It wouldn't significantly improve memory safety IMO. Adding a "slice" type with checked bounds (something basically every C codebase in existence ends up reimplementing somehow) would be a much greater improvement IMO.
But overall even though I still use C almost daily, I'm a bit skeptical of the committee's direction with these changes. They added half assed generics through macros, now a defer mechanism and a bunch of other stuff that's, IMO, out of scope for C. People have already tried to make a "better C" with all these bells and whistles, it's called C++, and it's still mostly backward compatible with C.
IMO C should be considered to be in "maintenance mode" these days. And again, my IRL job involves writing a lot of it, so it's not like I don't care about it.
Yup, there is a group of people who think that we should add brakes and lcd displays to horses because cars have these nifty things. For some reason, they don't understand it's ok that horses are not used for everyday travel anymore.
I hate the mess that c++ is. It started out with a object based programming paradigm with c like syntax. Then generics/templates were added. Then we have modern c++. It's 3 different languages crammed into one. The c++ committee has a serious case of nifty-itis.
Why spend thousands, if not millions of dollars, on rewriting existing codebases when they could help fixing the existing toolset and make it safer?
I don't get it.