And only 20% of memory related bugs are use-after-free which the borrow checker fighting is for.
And 100% of the use-after-free exploits were to gain admin rights on an already hacked Windows (all windows) computer.
So for the vast majority of people the borrow checker adds nothing.
The vast majority of memory safety bugs (extreme pro level, super hard to exploit, only worth it in massively adopted evil outer world facing software) can be fixed by using C++26 with array bounds checking and forced initialisation.
These last two things that Rust forces catch 70-80% of the memory problems the borrow checker only 20-30% only use-after-free.
Most problems by far for normal developers are supply chain attacks, exposing api keys, remote code execution, wrong input validation, wrong auth-flow.
You're reading the CVEs of sudo and ssh and think your code will be hacked like that.
PHP is memory safe and still many people hack wordpress plugins.
But no developers working on projects that have been so ultimately battle tested that only memory safety issues remain do that. Professional C++ developers use RAII and containers. If you use raw pointers or raw arrays in C++ you will get 200 code reviewers lecturing you. You will never be able to for long.
Unless your point is merely that average Joes write such terrible code that you don't even need memory safety issues to exploit their software, [citation needed]
Google says memory safety issues are 75% of exploited zero days. (https://security.googleblog.com/2024/10/safer-with-google-ad...)
Which isn't to say Rust wouldn't have caught many of the other memory safety issues, but 75% is horribly misleading.
Which is... true? but irrelevant. Such applications are not suggested to be ported to Rust. Of course, some people still do that, because they like Rust; but that's their personal choice.
For a language as ugly as Rust, my thought is that people should actually be using Ada, and have a mathematically provable correctness angle; not just a replacement for C/C++ with memory safety.
how old are you?
Look for example top 500 CVEs of this year (after many fixes in C++, not right when the 70% memory issues in Chrome came out).
Look at top 10 CVE github 2025 (zero memory related does not make it).
Look at that sudo-rs was not allowed in Ubuntu because it's not as safe (way worst track record) than the C version, almost all is input sanitation.
Look at wordpress plugins hacks, all PHP all memory safe language. Compare that to HAProxy and Nginx (C).
Etc.
The borrow checker does add something, but it definitely costs something as well in multiple ways, also in terms of how it is done in Rust and at a programming language design perspective.
It would be very funny if you were batting for Rust, and just having a laugh at others here.
Take ladybird (last month blog; not that ladybird stands for all projects out there, of course; it is just an example):
https://ladybird.org/newsletter/2026-05-31/
"The HTML parser is now written in Rust" "The Rust parser is also about 10% faster than the C++ version it replaced,"
I am not saying this is a systematic analysis by far, but Rust is pushing into domains where C and C++ dominated in the past. And that seems to be a real push. To me it looks as if both C and C++ are standing to lose some ground in the next few years, directly to Rust. Perhaps even via snowball effect.
I think it's also a big sign that the linux kernel adopted rust and not c++. (only for small parts but still)
When C++ people say they think there should be C++ in Linux, their proposal usually begins by proposing that it "should" be possible to just compile Linux as C++ software. This doesn't work because C isn't just "C++ but old", and they rapidly lose interest.
Which of course also feeds into Linus' semi-fair claim that not allowing C++ keeps out the low effort wannabes who would plague such a project. This makes C++ developers very angry, but part of the reason why is that it's true, C++ does attract these people.
The Rust for Linux people wrote a lot of code, a lot of documentation, they did Q&As, they worked very hard to actually deliver the idea to the kernel community, it's a totally different approach, it's a lot more work but some people thought it was worth the work.
If they rewrote it in C++ again, they would have most likely got the same result because they got a chance to fix a design that might not have been most optimal.
This speculation has been offered every time. It's not crazy to think this might be true, but it's also not crazy to think that if C++ keeps leaving performance on the table and Rust doesn't that adds up for real projects.
When Titus wrote "ABI: Now or Never" in 2020 he estimated 5-10% aggregate loss. Things that you could fix, if you started over, but C++ refuses to do that because of ABI and so it doesn't have these fixes, whereas in most cases† Rust does. So I can well believe that a blow-for-blow port could get you 10% perf win.
† One of the examples Titus cites is the "Small String Optimization". Rust deliberately doesn't do SSO for its standard library collection String, but several really nice SSO optimised types are available, including ColdString and CompactString, which are way better than what's provided in C++ if that's what you need.
On publicity side / propaganda / some specific areas you might have a point. Practically amount of C++ code being in active development (I wat to stress this particular point) dwarfs that of Rust despite all that high profile pressure.
Personally I consider languages as just a tool and do not get hung up when client prefers this or that and I have developed all kinds of software in many languages.
If asked for my own opinion - for general development I consider Rust very restrictive and poor expression-wise comparatively to C++, I think it is a case when developer become servant of a tool.
P.S. last sentence edited
Depends on the domain, there are enough fields where Rust still doesn't have an answer for.
Example, the compilers it depends on (botstraping on Cranelift when?), Khronos and POSIX industry standards, HFT, HPC, console devkits, AI frameworks, VFX reference platform,....
It will get there, eventually, maybe.
Rust also requires libraries to be safe regarding unsafe, no matter what kind of insane input that is given to the library and that would otherwise potentially be security issues. Which is too difficult for many library authors.
And unsafe in Rust is so difficult that many library authors throw their hands up, use Miri, and hope for the best. Even though Miri, all respect to it, has bugs, probability-based testing and other limitations and issues.
UB in both user library and standard library:
https://materialize.com/blog/rust-concurrency-bug-unbounded-...
I directly tackle the concerns you mentioned, and as a followup I'm actually working on formally verifying the library as well (I've had some success and will publish an update regarding this).
In broad strokes it's correct, this stuff happens and it's hard to be correct all the time. But are you trying to make a point? Or just ranting?
Also that linked issue was considered a CVE and is fixed (as the article says).
I have no idea what are you talking about, no_std is just completely irrelevant here.
> Nor if one of the soundness holes in the Rust programming language itself is encountered
Have you actually examined those soundness holes? It is basically impossible to hit them without writing code which is meant to hit them.
And this is also noted in a footnote.
> Nor if there is UB in one of the libraries used as a dependency by the library you are using
If we treat a Rust program globally, this is kinda true. A more true statement will be that UB cannot happen without unsafe code somewhere, including in dependencies (and the original statement can be interpreted as saying that).
But the true power of unsafe is that it's local. If you've reviewed a library and its unsafe is sound, you can ignore it for the rest of the calculation. And of course, the more people review a library the more likely it is that it is sound.
> Which has happened many times, since the Rust standard library is full of unsafe
And here again the post's point stands: many CVEs in std are artificial, you can't exploit them without writing a program that is meant to be exploited. Such thing will never be a CVE in C/C++'s std.
> Rust also requires libraries to be safe regarding unsafe, no matter what kind of insane input that is given to the library and that would otherwise potentially be security issues. Which is too difficult for many library authors.
That is true, that is in fact the post's point: that if they fail this, a CVE will be filled, even if exploitation is just not possible realistically.
But there is a very simple solution for library authors: don't write unsafe code! You don't need to, the vast majority of times. And if you do not have the knowledge (which indeed is more complicated than in C/C++) how to not have an unsound API, then you just should not write unsafe code.
imo one of those soundness holes is caused directly from trying to prevent UB - integer overflows. It is inconsistent in Rust what happens in that scenario depending on compiler flags, which basically just makes it UB for any given piece of code. And, unfortunately, default release mode behavior is unsafe.
Am I missing something?
I know this doesn't stop runtime problems in release builds, but i'd have thought this sort of simple precondition check would help users find problems in their library useage.
It's not going to stop you passing a non-terminated string, or other such invalid input though, which is I guess more the point, that it's totally possible in C to produce good looking but actually invalid arguments that can't be spotted at runtime without UB (out of bounds access etc).
Edit: Actually thinking about this more, I guess the problem is that you are likely linking against a release library implementation, so it's not possible to add a precondition without introducing a runtime overhead, which is probably more likely what we are talking about with this case.
If everyone expects specific behavior - ie it’s in the contract - you require that contract.
Indeed. Adding an assertion to a single function isn't a big deal, but if every function has to check all of it's arguments, that's going to add up. And even if you could have the assertion only in debug builds, that isn't enough unless you have a very exhaustive test suite, because an edge case could trigger undefined behavior in production in a way that wasn't exercised during testing.
In fact, the fact that the rust compiler adds runtime checks for array indexes if it can't prove the index is in bounds is a criticism some c programmers have of rust.
And the fact that after a half a century we're still debating how much we really need to care about U stuff like this when we get severe bugs in a major piece of software written in C seemingly every week is a criticism that pretty much all Rust programmers have of C.
Most systems languages, with exception of C, have ways to do bounds checking, even C++ and Objective-C, by using the respective collection classes.
And as as the Cloudflare incident showed, a Rust unwrap can have equally bad consequences. (or as Ariane 5 showed, a safe overflow in Ada can have explosive consequences)
For availability and stability concerns, the C approach is actually better, but for security and reproducibility, it is not.
In any case, you can also configure GCC to not do this, and you can also configure it to insert explicit null checks before dereferencing a pointer. So C can offer you security and reproducibility (in this aspect).
For the first issue of complexity, the reply is along the lines of show me the code and then either nitpicking that to pieces or explaining in several paragraphs how the behavior is perfectly reasonable and in fact quite easy to understand. Beginners get intimidated, professionals don’t have time to write novels on HN. Complexity in Rust is systemic. It’s little things accumulating and amplifying each-other that add up to having to spend significant time just designing types to satisfy the static analyzer. Many Rust programmers seem to see the type system as a hammer to be used liberally, an predilection also known in the C++ metaprogramming community.
On the second topic (also present in this thread) the counter-argument is that other languages do it too and nothing bad happened so far. The former is not valid, because Rust is uniquely bad in its competitor group and security by waiting is not a valued approach.
This is honestly not intended to pick on C++ as a Rust fanboy, however. It really isn't.
For instance, to be a little unpolished, I would shrug off the unwrap incident as doing it the C++ way and pretending that the complexity does not need to be solved right then and there because ItShouldNotHappen or IKnowWhatIAmDoing.
I prefer Rust over C++, but I do not hate C++. This isn't even about C++ anyway.
When it comes to out of control dependency trees, I agree with you. But there is a trade off here too and that is that either you implement the thing or you externalize it. I use both approaches myself and am in no way excusing anything or attempting to be Rust's defense lawyer. There definitely seems to be a leftpad-problem brewing in the Rust community.
Arguably less bad than silently corrupting your data and forcing you to do CAPTCHA everywhere.
Which is what the parallel Perl(?) component was doing at the time.
Rust solution gave a clear signal something was wrong, the other solution was slowly annoying everyone and pushing them away.
$ gcc -Wall -Werror -x c - << EOF
void f(int x[static 1]){}int main(){f(0);}
EOF
<stdin>:1:37: error: null passed to a
callee that requires a non-null argument
[-Werror,-Wnonnull]
1 | void f(int x[static 1]){}int main(){f(0);}
| ^ ~
<stdin>:1:12: note: callee declares array
parameter as static here
1 | void f(int x[static 1]){}int main(){f(0);}
| ^~~~~~~~~~~
1 error generated.
It can be done, though it usually isn't.His mistake was making _all_ reference taking functions also accept null. In Rust functions opt into None | Some
This comes up with C# which must have default(T) so references default to null. In Rust there is no general default(T) that must always resolve
However, Rust seems to trade memory safety vulnerabilities for supply chain risk.
Thankfully the community has built `cargo-vet`, which is basically a best-in-class distributed auditing system.
how is rust special in this regard?
1. Each crate you depend on generally comes with dozens of its own dependencies.
2. A large number of crates have few downloads. You can use blessed.rs to try an find "trusted" dependencies.
3. Cargo comes with "build.rs" for compile time code execution. Basically, your code (or your dependencies) can run arbitrary code when it first gets compiled.
4. A Github account is required to publish crates to crates.io (this sucks if you don't want to be locked in to another Microsoft system).
These are just a few of the issues I have had with Rust before switching off it.
edit:
Point #4 is personal for me. I have multiple crates published on crates.io and I cannot log in and manage them because I deleted my GitHub account a long time ago. I wonder if someone could create a GitHub account using my name and claim ownership of them...
So, tell me what compiler option disables non-modern C++ code? Is there one that enforces that every single variable including stack ones work like unique_ptrs without paying the price?
How about safety checks in std; is there an opt-out style safety checks where I can ensure that I'm not adding random things to a map with the [] operator, the library checks size of vector when I access elements in non-performance-critical code, anybody can use iterators safely without being able to write code that can change contents of a container?
How about std::thread? Is there an enforcement switch that I can only pass in things that work exactly like trivially_constructible<T>s, unique_ptr<T>s or shared_ptr<mutex<T>>s and nothing else?
Is there a compiler switch that completely goes against https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines... and ensures that no unchecked pointer access happens without explicit approval from the developer?
If those all exist, is there a movement to port many of the core building block libraries to that special compiler including std without being afraid of breaking ABI?
Those are all what Rust developers (who were or still are quite advanced C++ devs, btw, not people who are afraid of using raw ptrs) get freely from the Rust compiler. A lot of "modern" C++ code still contains and, by design, cannot avoid creating unintended and unlimited UB.
Enable warnings and WError
Use clang tidy and other static analyzers
Actually use a modern compiler and enable the safety features they ship with
Most of these things have solutions that would take years of work in an existing project so it isn't done
And it takes significantly more effort to write good modern C++ code than Rust code
So Rust wins
But I don't like writing Rust code, I do enjoy writing modern C++ code, the tradeoff is modern C++ can be a tooling nightmare... Try shipping a modern stdlib on an old platform, it is truly infuriating, I don't want to be a build systems expert but I need to be to use a safer alternative.
This is the blind spot that prevents Bjarne from taking significant steps needed for C++ to catch up. He's still seeing C/C++98 as the problem to solve, while Rust sees Modern C++ as the problem to solve.
The problem of TypeScript, is that you can still write JavaScript with all the WATs, same applies to any language that tries to be TypeScript for C.
However many of us actually think that Rust is also not the answer for everything, there are plenty of safe languages that could be used instead of C, C++, Rust for plenty of scenarios, and aren't because of cultural issues.
And there are plenty of ways to cause UB with modern C++ idioms.
Beautiful modern C++ unfortunately only exists in conference slides, recent C++ books, and top performer teams.
My main use for C++ outside hobby coding, is to integrate native code into managed runtimes, most of the time the code looks closer to C with Classes than anything past C++11, even if it was newly written yesterday.
1. https://youtu.be/U46fJ2bJ-co?t=2780
and Ryan asked Bjarne about memory safety. Bjarne brushes it off and says that in almost all cases where we see memory safety issues, they are either
1. Being written in C style C++ and not using "Modern C++" 2. Being written in C
He then goes on to say say that Modern C++ and where it is necessary, hardened libraries, go a long way to making these problems non issues. I'm not a C++ guy, so how much of this is true? What do the C++ developers think about this?
I've postd the whole message if people would like to read. It's about 46minutes into the video
Ryan: One thing that I think C++ is uh infamous for is kind of like memory safety issues or kind of foot guns that exist there.
Bjarne: I'm so tired of that. Um I haven't had those problems for years. Um, and somebody did a a study of the obvious problems with buffer overflows and um people hacking in using that kind of stuff and uh almost all of the uh these cases when people writing C style code or in C and uh Herb Server has a a talk with with actual numbers and they they are quite significant. It's it's sort of that kind of problems more than 90% are for people that don't write modern C++. They they use raw pointers to pass things around without um the number of elements. No fat pointers, no spans. um you you have them in C++. You can use them. You can use uh vectors. We have hardened libraries. Everybody has hardened libraries that that does the runtime checking. Uh Apple has it. Google has it. Microsoft has it. It's just not standard till now. C++ 26 has a hardened option that are standard. uh and the work I'm doing on profiles will give you a way of guaranteeing that you don't do the stupid things. Um so anyway, uh fundamentally theoretically the problem was solved many years ago and people just do what they've always done and get the problems they've always had. And uh that makes me sad and uh it's one of the things that makes me work on uh coding guidelines and on enforced profiles and on education. I mean education is one way to solve the problem. Is there a way to get the compiler to just prevent people from doing all those risky things? And is that enabled by default in modern C++ today? No, but it should be. I'm proposing that for C++ 29. Uh the simpler versions of that should have been in in in uh C++ 26, but there are still a lot of people even in the C++ standards committee that are very devoted to uh their old code and their old ways of doing things. Um there's people who says you should only standardize what is common in industry. But when the bugs are common in industry, you should do something else. The standards committee is a a topic I
> We adopted Rust for its security and are seeing a 1000x reduction in memory safety vulnerability density compared to Android’s C and C++ code
Maybe the android team could have gotten the same benefits by simply auditing and modernising their C++ code? I'm not convinced. Google has some amazing engineers. They've been using hardened standard library variants for a long time - much longer than they've been part of the C++ standard. If google is still getting large security benefits from adopting rust, I think the benefit in rust is real and Bjarne Stroustrup is wrong.
[1] https://blog.google/security/rust-in-android-move-fast-fix-t...
First of all, Rust is default safe. In C++ developers always trade performance for safety, in Rust they just swallow the penalty (which is often still performant enough). C++ code will often not be as memory safe as it could because someone decided to not use particular checks (like compiler-driven integer overflow checks).
Secondly, Android C++ code is not particularly high quality, also when it comes to memory safety. A lot of it is also quite old. I would consider it your average massive project, not a masterpiece coded by amazing engineers.
Thirdly, it has a massive target on its back and is under attack by pretty much everyone. They have to use whatever they can to keep up with the attackers.
Several companies have these issues and approach them in different ways. Rust is a very attractive approach for developers, since it’s just another programming language. It’s also quite ugly, people complain about its complexity and is unfortunately suffering from dependency explosion. I hope it’s a stepping stone to something better.
You can see comments on /r/cpp here: https://www.reddit.com/r/cpp/comments/1tgtllt/bjarne_stroust...
There is a significant discussion about it.
However, there are also a number of other threads on /r/cpp where you can read about people's opinions. https://www.reddit.com/r/cpp/comments/1rsmw5j/c26_safety_fea... is one sort of recent (three months ago) thread that I remember having quite the discussion.
My take (which is, given that I worked on Rust, a bit biased, but I intend to be truthful regardless) is that there are some folks who agree with Bjarne, but also many who do not.
Time will tell.
I'll believe this when he can actually point to non-trivial, real-world C++ codebases that have managed to avoid having memory unsafety following these techniques. "It's technically possible for this issue to be avoided" is a lot easier to say than it is to actually make work in practice.
If Apple and friends have a secret recipe for avoiding C++ memory vulnerabilities, maybe they should start using it to avoid stuff like this: https://nvd.nist.gov/vuln/detail/CVE-2026-20700
See Meet with Apple, security event.
Naturally they aren't going to throw away LLVM, DriverKit or Metal Shading Language, so there is a compromise there.
About twelve months ago, Bjarne wrote a paper named "21st Century C++" for WG21. In that paper Bjarne begins with a 10 line C++ listing which he says is equivalent to a fairly trivial awk program. It's a needlessly bad program which in fact has Undefined Behaviour, as I pointed out here (on HN) at the time.
So when Bjarne says he hasn't had this problem, you can take that one of these ways:
1. Bjarne doesn't understand that "this problem" includes all UB, meaning he is grossly incompetent, you should disregard his opinion about this stuff.
2. Bjarne is deliberately lying to you, he knows he still has this problem but for whatever reason he wants you to believe he fixed it. You should disregard his opinion about this stuff.
3. Bjarne is too ignorant to even recognise that his program has UB, once again you should disregard his opinion about this stuff.
a rule of thumb i follow is that the second someone starts comparing or talking about the number of CVEs, i just ignore whatever they say next. its hard to think of a more useless metric than "number of CVEs", especially now.
(edit: the people disagreeing are encouraged to share how you use "number of CVEs" to inform your decision making)
"Especially now" all these infosec folks "need to get CVEs fixed because compliance/SOC2, etc" and they will be even more up your a*!
Something has to change with how compliance works. It is so outdated and crazy.
Determining the impact of library bugs can be really hard. For example, some functionality might be so broken that it's simply impossible to use correctly, so a buffer overflow on top does not make a difference. Or a buffer overflow vulnerability triggers consistently during system boot, so that you never get to the login prompt. These can hardly be considered vulnerabilities. On the other hand, we have clear buffer management bugs, where we must expect that there is application code out there which specifies tight buffer bounds and requires that the library stays within that buffer. (Rust should help here, at least out-of-bounds accesses should turn into panics.) But most bugs are unfortunately somewhere in the middle. Tools like Debian Code Search can provide some evidence. But in the end, it's more subjective than I'd like it to be.
On the extreme end, we have compiler soundness bugs. I'm a bit of worried that I'm hitting any of those when I'm tweaking the types until the compiler no longer complains. Beyond the basics, I really don't have a grasp of Rust's type system rules. But I suspect they very difficult to hit by accident, and even if I do, the code must be miscompiled in meaningful, but difficult-to-notice way. All that seems rather unlikely, which is why these bugs aren't treated as vulnerabilities.
I really think we need some corrective factor (such as potential implication impact) when determining whether toolchain bugs are vulnerabilities.
> I'm not convinced this is true.
But it is. It is true that Rust libraries could take this position of "any API misuse causing vulnerability is a CVE" more to the extreme, currently it is applied to memory safety but it could be applied to panics as well. However it is still true that pretty much all Rust libraries treat API misuses that cause UB as a CVE, and pretty much no C/C++ library does that, and that inflates the number of Rust CVEs.
> On the extreme end, we have compiler soundness bugs. I'm a bit of worried that I'm hitting any of those when I'm tweaking the types until the compiler no longer complains. Beyond the basics, I really don't have a grasp of Rust's type system rules. But I suspect they very difficult to hit by accident, and even if I do, the code must be miscompiled in meaningful, but difficult-to-notice way. All that seems rather unlikely, which is why these bugs aren't treated as vulnerabilities.
Rest assured that you are much more likely to hit a miscompilation in your compiler's backend, and that it is much harder to detect.
The LLVM provenance bug is a really nice example. The Rust which tickles this bug (LLVM emits nonsense, claiming that two integers a and b are different but then calculating that a - b == 0...) is fairly clear, you wouldn't write it by accident but it's obvious what it should do, and unsettling to discover that the bug isn't in Rust's compiler frontend but in LLVM.
You can write equivalent C or C++ to show the bug with Clang - but when you try to write it you'll struggle, not to reproduce the bug per se, but to stop writing Undefined Behaviour, which invalidates your bug report because the LLVM devs will say "This is UB, working as intended". The non-UB reproducers are much more elaborate than the safe Rust was.
I mean, this is basically true. And it goes beyond type safety - there have been CVEs filed against the Rust stdlib for TOCTOU problems of a kind that the C++ stdlib is absolutely replete with (often the exact same ones in the exact same places, to the extent that comparable APIs exist) which ended up being fixed quickly in Rust and largely ignored in C++, if anyone bothered to file in the first place.
For sure does create headaches for those who need to categorize CVEs by impact, but on balance I don't think it's a bad thing for the ecosystem. Creating a culture that wants to fix soundness issues rather than mark them as WONTFIX with a line of documentation is a core principle and value proposition of Rust in the first place.
Quoting https://cor3ntin.github.io/posts/safety/
> But the borrow checker is not what makes Rust safe. Rust is safe because it decides to put correctness first by default.
> Rust is safe by culture.
Better to pay a penny to fix it today than a pound to deal with the fallout down the line.