USA presidency says "Future Software Should Be Memory Safe "

I think a big reason why C/C++ are so unsafe has very little to do with the actual memory management, like malloc and free, and everything to do with just the general lack of type safety of those languages. Memory safety in my opinion is merely a consequence of that deficiency. In C and C++ nothing enforces correctness, because it’s not built in the semantic of those languages, a int can freely be a char, on one platform some type_t is defined as a long, on another it’s defined as a long long. Compiler flags are not a solution either, because they allow you to bypass those warnings, which a compiler should not allowed.

Types are the fundamental building block of a statically typed programming language, if you can’t rely on them, then of course the rest will go south. That’s why Rust and Zig are such an improvement. Even if you were to give Zig the build system of C, and the std of C, I would still use it because the type system is fundamentally better. C++ attempts are just not good enough, things like smart pointers, and optional, give you the illusion that you are safe and correct, which again is not enforced fundamentally by the type system at all, you are just gluing some templates to get a dash of safety.

I hope that as both Rust and Zig grow, more people realize that the fundamental problem with the languages they are trying to replace is not the lack of “memory safety”, but really the lack of type safety. As anyone with enough time can write memory safe C/C++, what makes it unrealistic is simply the deficient type system.

4 Likes

I disagree that C++ isn’t necessarily type-safe, or that C++ can’t be written in a type-safe manner. If you stick to C++ and don’t use c-style casts, reinterpret_cast, and raw pointers, you have a degree of type-safety. It’s not absolute, of course; if you want that, you should probably go write your project in Ada. (I bring Ada up here because Ada is a phenomenal language, and though it has it’s issues and warts, as does any programming language, it’s probably one of the safest, if not the safest, languages out there, and I don’t think even Rust has managed to get close, but it does try.) No, the problem is that (modern) C++ still allows unsafe methods. I suspect that this is for performance, though it’s hard to buy that excuse when I think the checking if a std::unique_ptr is nullptr or a std::optional is valueless conditional would take only a few cycles, assuming the compiler doesn’t figure out it’s value beforehand and either optimizes it away entirely or gets rid of the conditional check and leaves only the “throw this exception” or “return it’s value” statements in it’s place. The (proper) way to work with std::optionals and std::*_ptrs is to be smart, too, because a “smart” pointer is not going to protect you from your own bouts of idiocy. (I for example will use std::unique_ptr/boost.unique_ptr wherever I can, and rarely ever do I use std::shared_ptr, even in concurrent or parallel code.)
No, I think the real problem underlying insecure code is not the language. C/C++ could be the most type-unsafe language in all of existence and I still would state this as fact, because the real problem is the fact that those that teach programming (colleges, universities, schools, …) don’t emphasize secure coding practices at all. At least, a lot of them don’t. Mine for example didn’t; oh, there was plenty of emphasis on writing code that actually ran in parallel, but there wasn’t a peep about secure coding practices or writing secure software. This doesn’t just happen in the education sector, but in tutorials and books too. So people learn how to code, presumably in C++, but what they don’t learn is about the unique/shared pointers, optionals, etc., instead learning about C functions, where type-unsafety is guaranteed. (One of my professors, I quickly found out, was well-known for writing half-C/C++ code, and teaching his students, myself included, that we too should do this, because it was what he knew, and I don’t know if he even knew about the advancements of C++11/14/17/20.) So, here we are, with students learning that writing insecure code is fine, and then they go into the workforce and… Wouldn’t you know it: this same attitude is promulgated and encouraged, which further makes the entire concept of writing secure code less and less known, unless your in a sector where it’s legally required (because if you don’t, the government is going to fine you into non-existence and most likely jail your C-suite executives, something I think should happen far more often than it does, but that’s another topic for another day). My point is, people go on and on and on about writing memory-safe code, or safe code in general, but this isn’t taught from the beginning when people learn how to code. It’s only taught when it’s absolutely required, and by that point, your so used to writing code in an unsafe manner that it’s difficult to change that mindset.

2 Likes

UAF is not a “footgun feature” of languages like C per se,
it’s a matter of how a programmer is writing his/her code.

One can do it amenable and careful (regardless of a language),
one can do it sloppily.

As to UAF in C.

Well, just write something like this, every time and everywhere:

if (s->ptr) {
    free(s->ptr);
    s->ptr = NULL;
}

And if your s->ptr in a particular instance of typeof(s) can change from NULL to NOT NULL while a program is being executed, just check if this particular instance has it’s ptr field is really not null.

To me, UAF is a sort of a fringe concern - you will never invent a compiler that would be more smart than a programmer who wrote that compiler.

UAF is very dangerous and only possible easy in MMM languages with no built-in safety. This argument is on the level of “just don’t write bugs, then you wouldn’t have bugs”, and it is a goal of Zig to make it easier to write software in the way you describe.

I agree with you, and it seems like we’re on the same page. Yes, it’s definitely possible to write flawless C/C++ code, and some people dedicate their entire careers to mastering it. However, I believe that while it’s not impossible, it’s inherently impractical and challenging. It’s not the kind of challenge that’s rewarding either. Take Rust, for example. It’s tough to write Rust code that performs well because you have to constantly consider ownership and lifetime rules. It’s a different kind of challenge, one that pushes you to rethink your approach and expand your coding skills.

C/C++ are easy to write, everything basically compiles, giving a false sense of proficiency. However, writing code that’s both correct and efficient in C/C++ is a constant battle against your own knowledge of the language, it’s annoying. It’s too easy to fall into traps and bugs, and while it’s not impossible to get it right, it’s not something everyone can achieve consistently. Shifting much of this burden to the type system and compiler improves a language’s practical safety. While opt in features like smart pointers are a step in the right direction, they still require you to use it, it’s not a requirement from the language itself.

2 Likes

If you haven’t already, you should watch the video that @Sze posted - you can use after free in Rust with very trivial examples. It’s also important to point out that all software has bugs… we’ve never written a perfect language so this just isn’t historically true. I’m not saying there isn’t value in these types of languages, but this is an optimistic take.

Of course you can, it’s just much harder :stuck_out_tongue: So yes, I revise my statement: it’s only easy to do in MMM languages.