A neat detail that bears driving home.
First, a quick note:
First, a quick note:
In this article, the phrase “lines of code” will be abbreviated as “LoC”, with “kLoC” and “MLoC” referring respectively to thousands and millions thereof. Also, the phrase “memory safety vulnerability” will be abbreviated as “MSV”.
Rust has been making waves within the software industry for more than a decade now. From what I can tell, it really picked up steam after the release of its 2018 edition –this is more-or-less when I came to know about it, too– but some waves can be felt as early as 2014, even before its 1.0 version released.
The biggest wave, of course, was its promise of memory safety. Thence, a healthy skepticism emerged in response: “Just how memory-safe is Rust, really?”. It's one thing to promise memory-safety, but another thing to actually deliver. After all, at the end of the day, Rust values usability and practicality even higher than memory-safety; therefore, for a maximally usable and practical language, a very-small-yet-non-zero amount of memory-unsafety must necessarily remain.
The comparison gets slightly more muddled due to the distinction between safe and unsafe Rust. Safe Rust has more-or-less zero MSVs by design. But how much of the code we write has to be unsafe, and what is the MSV density in unsafe Rust code? After all, there exists a very literal selection bias: Rust's unsafe blocks gather all of a code-base's most dangerous operations, so a pessimistic yet realistic expectation might very well be that unsafe Rust's MSV density will be even higher than that of completely memory-unsafe languages.
As it just so happens, however, we have hard data about this. This is mostly thanks to Google: in developing Android code, they realised that by far the most MSVs occur in new code. Therefore, they are progressively switching their new code from C/C++1 to Rust. Same code-base, same developers, same company, same practices; the only thing that's changed is the language. It is therefore no surprise that this series of articles is hailed as the golden standard when it comes to comparing the safety of Rust and C/C++.
As of early 2026, the most recent article about this subject is Move Fast and Fix things. Using its data, we can make the comparison between two languages:
- The first has a well-established MSV density of around one per 1 kLoC, measured reliably over several MLoC.
- The second has seen, amidst around 200 kLoC, just one MSV. As in, its MSV density is so low, that we can't even be sure we're measuring it accurately.
The reader might reasonably expect the above comparison to be between C/C++ and Rust. Psyche! It is not. The above bullet points compare C/C++ to unsafe Rust specifically. With Rust overall, assuming a fairly generous 5%2 of unsafe code, the difference is more than three orders of magnitude.
Let us put this difference into perspective, shall we? We can say “orders of magnitude”, but that doesn't really evoke a particularly vivid mental image. What do two and three orders of magnitude really look like?
Well, in the context of speed:
- Two orders of magnitude is the difference between a particularly slow walker and a Formula One car.
- Three orders of magnitude is the difference between a particularly slow walker and a SR-71 Blackbird.
A quick primer on the Blackbird:
The SR-71 Blackbird has been, for the past several decades, the fastest air-breathing jet aircraft that humanity has ever produced. It can go around Mach 3. If it could sustain this speed indefinitely, it would be capable of circumnavigating the globe twice in one day. Doing so westwards over the equator would make it experience 24-hour days, except from its point of view the sun would rise in the west and set in the east.Let me get the megaphone for this one, because it's an amazing point that apparently nobody thought to emphasise:
Even unsafe Rust is nonetheless two orders of magnitude safer than C/C++. Overall Rust's actual safety is at the absolute least 3 orders of magnitude greater than that of C/C++. This is the difference between a slow walker and Mach 3.
But how can that be, when there's the selection bias we mentioned earlier? I believe that this ultimately boils down to two important reasons, that even the blog-post mentions in passing:
- Rust offers local reasoning. Because C/C++ has great trouble establishing firm API boundaries, safety concerns basically amount to “If the consumer does X or Y or Z, disaster strikes”. Then, auditing consists of checking every usage and seeing whether conditions X Y or Z are being violated.
In contrast, Rust can afford to constrain unsafety within safe API boundaries, which in turn means that each API boundary can be examined in isolation from code external to it. Instead of saying “don't do X Y or Z”, we can afford to say “Y and Z can't happen by compiler guarantee, but the user might do X so we had better ensure it's handled safely”. - Closely related to that: Much easier auditability. If the amount of
unsafecode is one 20th of the total, then an MSV auditor's attention can be 20× more focused on what actually needs to be audited, instead of squinting at every single line for defects. In open-source crates, there have even been instances of nosy w⚓s dropping by unannounced for a quick audit, only to actually succeed in finding important bugs. (“Oh, this person processes untrusted user input usingunsafe? This smells dangerous, let me take a closer look… is it sound even in the presence of panics? Ah-hah! Gotcha!”)
═════════════════════════════════════════════════════════════════════════════
Yes, this article will be grouping C and C++ together. The secondary reason to do this is that Google's data does the same thing. The primary reason is that it pisses you off—yes, you specifically, the person currently reading this.
To be clear, a 5% unsafe code percentage is generally reserved for very low-level applications such as embedded operating systems. Higher than that goes beyond “this probably performs many low-level operations” and into “this number alone tells me that the code needs significant cleanup”.