Rust in Android: move fast and fix things
security.googleblog.com
security.googleblog.com
5 million Rust LOC
One potential memory safety vulnerability found
Rust is 0.2 vuln per 1 MLOC.
Compared to
C and C++ : 1,000 memory safety vulnerabilities per MLOC.
Key take.And I say this as someone who has never written a line of Rust in their life (some day I'll find the time).
On one hand, C++ is an incredibly complicated language that one can invest considerable amounts of time into. It also used to occupy a unique niche where you get tons of abstraction features yet as much blazing speed as you care to spend time optimising. Rust is encroaching on that niche.
On the other hand, C is an incredibly simple language, which does not allow for convenient expressions of particular abstractions. If they hated C++ because it was too hard to follow. What the code is doing, they probably hate rust for the similar levels of abstraction affordances.
When I hear the bad faith arguments from people who really should know better, what I hear is a group of scared developers who have been able to coast on their knowledge base for years or even decades, and are now feeling like their skill set is at risk of being unnecessary.
It always seemed like an unproductive attitude to have in a knowledge-based industry like software development. I am also a C++ developer, but you bet I am learning Rust on the side, because I think it's a good idea to skate where the puck is headed. I also learned enough of Zig to be dangerous a few months ago because it was fun.
Either way, I would suggest those developers reflect on the reason why they have this reflexive need to throw a wrench into any conversation mentioning rust. If their intention is to slow down adoption through hostile community sentiment, it's not working.
That’s certainly not the case for C++. The C++ language has evolved quickly, with a release every three years or so. One could coast, but they would be writing outdated C++ that no newcomer likes. That is, the entire organization needs to also coast for this behavior to be viable.
Instead I see most of the bad faith criticisms of Rust coming from aficionados of other languages in roughly the same space such as Zig or Nim, or occasionally Go. They whine because they think Zig or Nim should take the place of Rust.
>They whine because they think Zig or Nim should take the place of Rust.
How about because Rust Evangelism Strikeforce go after other language first? Every time a language in the same space comes they get asked if they are memory safe?
Things have died down now, doesn't mean it didn't happen.
I have some bad news for you. In the early 90's, C++ _was_ that language. Not only that, but at the time a lot of the reactionary criticisms of C++ by annoyed C developers had a lot more weight to them.
- C++ was slower than C, because the costs of vtables and exceptions was a lot larger and compilers weren't as good at optimizing.
- C++ was bug-ridden, both because it was easy to accidentally misuse the language, but also because compilers were simply buggy due to the complexity of the language.
- Many of the STL containers you know and love were missing from pre-standard C++, and even afterwards its implementation was commonly subpar, leading developers to either use their compiler-specific proprietary containers or roll their own.
- Streams were often the only reliable thing in the C++ standard library. It also ballooned compile times to the point of being outright banned from many codebases.
- Don't get me started on the utter nightmare that was sifting through compiler errors through misuse of templates...
So yeah, I don't want to hear other C++ developers whine about how annoying Rust developers are. We were just as annoying back in the day, with a worse language. Linus banned C++ from the kernel, and honestly he was 100% right to do so at the time.
So what?
It might be shocking for you, but every new messenger gets asked if it supports e2ee these days.
Why shouldn't people want to know about the availability of a massive advancement in the space of system programming languages?
There was a revival of C++ starting with C++11 and ending around the era of C++17. It was, frankly, great. However, a few things happened around and since C++20 that has caused the language to backslide.
First, it seems like corporate support for C++ has dropped significantly. Apple, having successfully replaced GCC with Clang for their own internal use, no longer cares that much about keeping up with the latest C++ features, choosing to prioritize Swift instead. Google seems to have slowed their contributions after being blocked from any commitments that opened up the possibility of breaking ABI. Microsoft has gutted their Visual C++ team, which has significantly slowed the implementation pace of new features and fixing bugs...unless they're related to Unreal Engine. There are also persistent rumors going around that Microsoft are working on their own project in the spirit of rustc-codegen-gcc, but for Visual Studio.
Second, it seems like a lot of the new blood that the revival decade had attracted to the C++ community and standards committee have stopped participating and given up. There's probably not one or two all-encompassing reasons for this, but the disconnected stories I keep hearing about just leave me feeling sad for the future of C++. Anecdotally, the ones that I see that are most commonly cited up are the horrendous rollout of C++ modules, the drama surrounding Safe C++ vs Safety Profiles, and the circling of the wagons around rot13_content_warning("pbaivpgrq puvyq encvfg") Arthur O'Dwyer.
If I had to pick one own-goal in particular that ground my gears from a technical perspective, it's the ordeals of the developer who tried to get `std::embed` into C++. Going through the standardization process was such a nightmare for her - including trying to convince the standards committee that it was a problem worth solving in the first place - that she eventually gave up and took the idea to the C standards committee instead. After a few rounds of back-and-forth feedback, C23 now has #embed. Not only did C get the feature before C++, but the C++ standards committee gave up whatever say they had in the shape of the final product.
That's not to say that I'm not looking forward to certain modern C++ features. Concepts are great, even if they fall well short of the original proposal. I use std::span and std::expected in every project I can, even if I have to use third-party polyfill libraries to deliver them. Modules could be nice when they're more widely supported. But _man_ the future of C++ looks pretty bleak from where I'm sitting, and it seems like the people in a position most able to do something about that future aren't making wise decisions.
First time hearing about the embed issue and god that person’s experience is awful: https://thephd.dev/finally-embed-in-c23 and it feels like a job for only the best project managers.
A lot of my coworkers get in this situation where, when a change in direction is made, they feel like we have to stuff the roadmap with work to rewrite everything. That work is... 0 value, in most cases, unless the decision we have made is intended to directly solve an issue in the existing code.
Many times I find that if you just do new work in the new thing, you'll "naturally" prioritize rewriting at the right rate. When we do it that way, we end up replacing, rather than rewriting, those legacy systems, which avoids the pitfall of trying to reproduce prior behavior, down to the bugs it may have had.
This is a general result regardless of what language you're talking about (unless you're really downgrading to assembly or something crazy). This of course presumes that the overall Rust (or other new language) situation is better than the existing one. It's not generally.
As an example, from https://android.googlesource.com/device/generic/trusty/+/c3f...
Many of the files in that commit have a lot of C-style code, yet are classified as C++. C and C++ are very different programming languages, and memory safety is arguably significantly easier to achieve in practice in C++ than in C, yet in the blog post, C++ is blamed for C-style code, and C and C++ are not differentiated.
Compare and contrast with https://android.googlesource.com/device/generic/goldfish/+/d... . That source code file has much more modern C++. Though even then, it contains goto, and modern C++ code reviews would normally not accept goto in my experience. I do not understand what Google Android is doing when its developers are using goto. Could they not have used lambdas in those places where they are using goto? The mixture of std::string_view and goto, modern and yuck, is disconcerting.
On a different topic, how much of the new Rust code is vendored dependencies? Is Fuchsia included?
Maybe the real value for Google Android that Rust holds, is that it mostly prevents C-style code from being written. And Rust does not support goto, and while I think an argument could be made that goto is OK to include in a toolbox, its usage should be very, very, very, very rare. Why does somewhat modern Google Android C++ allow goto?
I am not impressed by Google Android's C++ code quality. Are Google Android developers, independent of language, significantly below average?
C++ does have baggage, cruft and issues. But having strange C++ code (like goto) and also blaming C++ for C-style code, does not help paint an honest and accurate image. And if Google Android's C++ code review process accepts goto willy-nilly, I do not consider Google Android to be at all credible on any subject related to code quality, memory safety and security in any programming language.
Though, I suppose something like C++ profiles, just for modernization, might make it much easier to enforce and track that modern C++ is used.
Or any language with unsafe code blocks, which people keep forgetting also exist, while complaining about Rust, as if there isn't any other memory safe language.
With C++ you need external tooling to disable C like code, that a large part of the community refuses to adopt.
We're decades into the global warming era. You simply can't make some people accept evidence if the conclusions from that evidence would be uncomfortable to them.
If people don't take exploitability seriously, you can't make them. Well, unless you keep pwning them.
[0]: Or even whole-assed. Memory (un)safety is only one form of vulnerability.
I'm not sure if it is the best ROI to rewrite battle-tested tools in Rust, but it isn't like people are forced to do it. People have fun writing Rust, and want to work with it more, so that's the direction these projects take. And if you don't want to use these tools, the beautiful thing about Linux is that if you don't like the direction a distribution takes, you can always switch.
That said, memory safety is one criterion out of many that could be used to make that decision. For a large number of software projects, memory safety simply isn't a major concern. Ease of use, iteration speed, developer familiarity, availability of specific libraries, and so on, are often equal or greater concerns than memory safety.
So, sure, if you're writing a kernel, operating system, or a mission-critical piece of software, then Rust might be worth considering. Otherwise, you might be better served by other languages.
Rust seems to attract a certain mindset of mediocre programmers who yell "security" to shove their poorly written slower code down our throats.
Most of them seem to be former web developers who bring all their npm drama to stable C foundations
We're in C23 nowadays, and in Linux distributions there are plenty of npm like drama, one apt/dnf install away with pkg-config, or vcpkg/conan for the more modern folks.
Although I imagine there are a few still stuck in ./configure land.
Because it's not a silver bullet. That safety comes at a cost; Rust is much more difficult to learn than C or Zig and the compilation time for code with equivalent semantics is an order of magnitude greater. It has also added a great deal of toolchain complexity to projects like the Linux kernel.
People have decided that the pros outweigh the cons in those particular cases, but those cons exist nonetheless.
(fwiw, I teach undergrad systems programming in C, I use Python at the startup, and I use a mix of C/C++/Rust in research.)
I would personally much prefer to use Rust for code exposed to external untrusted input than to use C. I have substantially more confidence that I would not add exploitable bugs given the same time budget.
C and C++ are incredibly subtle languages. But you can get a lot of code written before you run into certain foot guns in C and C++. This gives those language a more enjoyable on-ramp for beginners.
In comparison, rust is a wall. The compiler just won’t compile your code at all if you do anything wrong. This makes the act of learning rust much more painful. But once you’ve learned rust, it’s a much smoother experience. There’s far fewer ways for your programs to surprise you at runtime.
1) Design in correspondence with AI. Let it criticise your ideas, give you suggestions on tools/libraries/techniques, and have concepts and syntax explained to you. Stay aware that these models are sycophantic yes-machines.
2) Implement yourself.
3) Debug in collaboration with AI. If you ask a question like "I'm getting [error], what are the most likely reasons for this happening?", you can save a lot of time finding the issue. Just make sure to also research why it is happening and how to solve it independently.
4) Let AI criticise your final result and let it offer suggestions on what to improve. Judge these critically yourself.
There is some worth in spending hours trying to fix a bug you don't understand, it builds resilience, helps you get familiar with a lot of language topics, and you probably won't make the same mistake again. But the above approach is a pretty good compromise of letting AI help where it excels, while still keeping enough control to actually learn something yourself.
I believe that Rust is the language benefiting the most from agentic AI, because the compiler is such a strong gate-keeper, and the documentation of almost all aspects of the language is comprehensive and clear. The biggest pain points of Rust are also reduced by AI: Front-loaded learning curve is softened, refactoring is something gen AI is actually decent at, and long compile times can be spent productively by already planning out the next steps.
Except in my experience, chatgpt and claude both struggle to write rust code that compiles correctly. Chatgpt is pretty good at complex tasks in typescript like "Write a simple snake game using (web framework x). It should have features X and Y". Its can be surprisingly good at some complex problems like that.
If you try the same in rust, it often fails. I've also had plenty of situations where I've had some complex borrowing error in rust code, and chatgpt just can't figure it out. It goes in loops. "Oh I see the problem. Sure, this should fix it ..." except the "fixed code" fails in just the same way.
I'm not sure why. Maybe there's just not enough rust code in the training set for chatgpt to figure it out. But rust is definitely a weakness of the current generation of models.
If a language is hard to write at first, it’s always hard to write. The saving grace of C++ is that one mustn’t use the overcomplicated functional aspects, template meta-programming, etc. Through some amazing circumstances, all of the above (or their equivalents) + async is exactly what idiomatic Rust code has become.
Inside Rust there is a not so ugly language that is struggling to come to light and it is being blocked at every step.
That seems obviously false. Most fancy programming languages are difficult to write at first, C++ included. But they all get easier over time.
Rust got way easier to write over time for me. I'm soooo much more productive in it now compared to when I started. Does C++ not get easier to write over time too?
Of course adding an additional set of tooling complicates an environment. I'm sure that was the case for Google in adding Rust to Android as well. And yet - it seems to have proved worth it. And I suspect that in the long term it will prove likewise for Linux, because Linux shares the same requirements and has a similar threat model it needs to guard against.
"This seems unrelated to the topic at hand, which is whether Rust results in a net improvement in the time required to deliver (systems) software"
A lot of your argument assumes that you've already have an entire working build environment readily available. If this is not the case, what used to be a fairly straightforward C compile now becomes an massive ordeal
Suppose we have a team of experts busily analyzing every single state of the code. They are reading/valgrinding/fuzzing/etc.-- in real time as the intermediate developer writes code.
Each time the developer tries to compile, the team quickly votes either to a) remain silent and leave the dev alone, or b) stop compilation because someone thinks they've discovered an invalid read/write or some other big no-no that the compiler will not catch (but the Rust compiler would catch).
If they choose b, the experts stop for a bit and discuss the clearest way to communicate the hidden bug. Then they have a quick conversation with the intermediate developer. Suggestions are made, and the whole process repeats.
Is this process substantially faster than just learning Rust?
Edit: clarification
It is misguided to say that recursive data structures should be easy to write. They are difficult to reason about and the Rust compiler is right to point this out. CS is not engineering, you should be writing those trees with a pencil on a piece of paper as Dijkstra intended, not in C.
And is your hand-written C implementation going to be safe and correct. You didn't mention any kind of locking or atomic operation, so is it going to unexpectedly break in a multithreaded environment?
The concepts of Rust are definitely more complicated, but in practice it just means that C makes it easier to shoot yourself in the foot. It's easy, but is that really the most important thing here?
In the same vein, driving on a modern busy road requires you to know about lanes, speed limits, various signs, traffic lights, rules of turning and merging, etc, etc. A road without all of that, where a steering wheel plus two pedals suffice, of course still allows you to drive, and drive fast, but it requires much more attention from a driver; many driver's mistakes are noticed later, and lead to more dangerous accidents.
This assumes a self-balancing binary tree must have nodes with parent pointers. Without those you don't need reference counting and without that you don't need `RefCell` either.
It does look like a silver bullet, actually. In the context of software engineering, "silver bullet" inevitably leads to Fred Brooks:
'"No Silver Bullet—Essence and Accident in Software Engineering" is a widely discussed paper on software engineering written by Turing Award winner Fred Brooks in 1986. Brooks argues that "there is no single development, in either technology or management technique, which by itself promises even one order of magnitude [tenfold] improvement within a decade in productivity, in reliability, in simplicity."
Reducing memory-safety vulnerabilities by 5000x compared to the prior approach is not just a silver bullet, it's an arsenal of silver bullets.
> the compilation time for code with equivalent semantics is an order of magnitude greater
The time it takes to write and run the comprehensive tests for C and Zig code to demonstrate anything even approximately in the ballpark of what Rust gives you for free is a multiple orders of magnitude greater than whatever time you spent waiting for the Rust compiler. Why care about the time it takes to compile trivially incorrect code, rather than caring about the total time it takes to produce reliable software, which is demonstrably lower for memory-safe languages like Rust?*
Nah. For me it induces vomit. Any time the vulnerability is mentioned a horde will arrive promptly and sing "rewrite the ... " in Rust.
For fuck's sake. We got it. We know it is mostly memory safe with bunch of other protections baked in. So go and rewrite it and then try to sell it to your customer and have them pay for this job. If you succeed - congrats, good for you and for the "victims". If not - stop nagging people who have other things to worry about.
So, that's why I completely dismiss it, it fraudulently attempts to champion Rust as an obvious replacement of anything. For those who think this has something to do with Rust specifically, no, we've held these reservations for promised replacement languages for decades now. There is no evidence Rust's borrow checker alone has overcome enough of the problems of any previous example.
A short criticism of Rust is, for a supposed systems language replacement, they let far too many features and first party magic (cargo) into the language.
Are 100% of those exploitable? This single ended statistic is simply not useful.
> Other types of logic bugs are also easier to avoid in rust because it's type system is quite powerful.
You have proof of this?
> Anyone who's actually migrated a code base from c++ to rust should be able to attest to the benefits.
That's not how these measurements work. In particular, modern C++ has many of the same advantages you just cited, so this claim is dubious in two ways.
And you've entirely failed to address the largess of Rust, which, again, for a "systems language" is entirely mismatched.
I'm not entirely sure where this idea even comes from. Why would it be desirable for a systems programming language to be sparse on features?
Modern c++ has none of the advantages I mentioned. std::variant is cumbersome to use and you cannot easily match on it exhaustively, std::optional and std::expected have UB if you look at the stored types without checking if it's valid first. I love c++ and still use it daily, but I also know I write more bugs when I use it compared to rust. I don't have hard proof that rust is less prone to other types of bugs but wouldn't be surprised if someone produces a blog post with evidence. If you're trying to make judgement without experience, then that's simply foolish.
I'm not sure why you would point to "bigness" of the language as a problem when you're fine with considering c++ a systems language. If you don't like cargo, you don't have to use it. There are other build tools that can integrate with the rust toolchain the same way you would do so with c++. If some libraries are not suitable, don't use them. There are plenty of c++ libraries like boost which I avoid because they don't work well for me too. Consider the way in which The Linux kernel is using rust the language. The key to whether a systems programming is useful is whether I can meet the constraints the software must run in, typically in terms of binary size, memory usage, and runtime performance. Rust delivers here and can be used anywhere c/c++ have found success.
Some more links/statistics (including on 0-days exploited in the wild) here: https://www.memorysafety.org/docs/memory-safety/#how-common-...
> You have proof of this?
One class of non-memory-safety bugs that safe Rust entirely prevents is data races: https://doc.rust-lang.org/nomicon/races.html
> That's not how these measurements work. In particular, modern C++ has many of the same advantages you just cited, so this claim is dubious in two ways.
Are the advantages in those cases (option/result) properly realized when it's just piled on top as something you could do?
I still have to be wary that, for instance, std::strchr could return a nullptr which I might pass on without handling. Plus even with std::optional<T> it's on me to remember to check val.has_value(), else it's undefined behavior to access.
Whereas in Rust, s.find() must return an Option<usize> because there's no null for it to return otherwise, and accessing the inner value (`match`, `if let`, ...) requires handling the Option::None case.
> And you've entirely failed to address the largess of Rust, which, again, for a "systems language" is entirely mismatched.
Large compared to C or Zig, but not compared to C++.
There's probably also 500x more people who know c to a given level then know rust to a given level.
If we have an analyzer that can find memory safety bugs in C, we could also just put that in the CI pipeline, or as a pre-submit hook before you're allowed to add code to a code base.
No man, it is possible to just do better, and this is an example of just doing better. The Rust is just better software. We can and should learn from this sort of thing, not insist that better is impossible and the evidence suggesting otherwise must be a mirage.
The graph about reverted code also addresses the "illegible bugs" argument.
As for an analyzer, that's what ASAN is. I hope I don't need to explain why that's not a universal solution (even though everyone should be using it).
The post you reply to does not indicate a misunderstanding of memory safety at all. .
Let's use an example: https://godbolt.org/z/TP6n4481j
The code shows main immediately calling a nullptr. What the compiler generates is a program that calls unreachable() instead. These are two different programs. If memory safety is "just" a bug, this would be a miscompilation. It's not a miscompilation though, because what I've given the compiler is something that resembles C++, but is actually some similar language where null dereferences are meaningful. The compiler only knows about C++ though and C++ doesn't have nullptr dereferences, so it assumes I haven't done that. Instead it generates a program corresponding to an execution trace that is valid C++, even if it can't see the call to NeverUsed(). If you use -O0, you get the segfault as expected.
A single instance of memory unsafety (or other UB) can take your program arbitrarily far from "correct". All other things being equal, a program with 1 violation might be just as incorrect as a program with 100. I could add a hundred more lines of safety violations after Do() without changing the compiled behavior. You don't even need to execute the unsafety to have "spooky action at a distance" cause that change.
[0] https://web.archive.org/web/20190406194101/http://colinm.org...
Many Rust proponents are experienced C and C++ developers who have dealt with this situation for decades. Given the language, it's understandable that compilers make the choices that they do. It's also understandable that programmers find it unreasonably difficult to reason about code written in such a language.
This isn't really correct and many programming language standards (including that of C and C++) don't support this view. Many language standards define a notion of conformance. Strictly conforming programs aren't allowed to invoke behaviors that which are undefined[1].
Conforming programs do not have this requirement and basically any non-trivial C and C++ programs are written to this rather than the notion of "strictly conforming".
Most non-trivial programs are not strictly conforming (including some C compilers themselves), generally because restricting the set of targets to something smaller than "any possible C implementation" is useful.
It is perfectly legal (and very desirable in cases where the standards fall short of usefulness) for a C compiler to define undefined behavior. What you compiled is still a C program, just one that isn't portable across the entire potential set of implementations.
[1]: Or unspecified or implementation-defined, for that matter, but this part tends to get left out of discussions.
Being simpler is not a given though.
"Knowing C" as being able to read and understand what's happening is quite separate from "knowing C" as being able to write it competently. Same thing with Rust: an algorithm written in rust is far from impenetrable for a non-expert, and even someone who sees Rust the first time but has enough experience with other languages.
C is not simple, it is inept. There are so, so many bargain-bin features and capabilities that it just cannot do that it ends up creating much MORE complex code, not less complex code.
I mean, just the pretense that simple tool = simple engineering isn't necessarily true. Building a home using an excavator and drills is fairly straight forward. You know what's complicated? Trying to build a home using only a screwdriver. Yeah. Good luck with that, you're gonna have to come up with some truly insane processes to make that work. Despite a screwdriver being so much more simple than an excavator.
Trivial example: you want to build a container that can hold data of different types and perform generic operations on them.
C++ and Rust? Easy. Templates and generics. C? Up until a few years ago, your options were: 1. copy and paste (awful) or 2. use void * (also awful).
Copy and paste means your implementations will diverge and you just artificially multiplied your maintenance burden and complexity. And void pointer completely throws away any semblance of type safety, forces you to write stupid code that's way more complex than it needs to be, and, to top it off, is horrible for performance!
That's just one example, but there's so, so many when you look around C++ or Rust enough. And these are not rare things, to me. To me, these are everyday coding problems.
Anonymous functions? There's another one. Encapsulation? Just making not literally every piece of data universally mutable? Not possible in C. Trivial in C++ and Rust, and it makes your programs SO much easier to reason about.
And Rust is significantly better at this than C++ for the simple reason that mut is a modifier. I’ve lost track of how many times I’ve listened to Kate Gregory extol the virtues of const-ing all the things, but people still don’t systematically add it, and, as readers, we’re left wondering whether things actually need to be mutable, or the author forgot/didn’t know to add const-ness to their code. With Rust having opt-in mutability, you know for a fact that mutability was a deliberate choice (even if sometimes the only motivation was “make the compiler happy”).
Adding const to _function-local_ variables only really matters when you "leak" a pointer or ref, whether mutable or const, to a function or variable the compiler can't optimize away:
std::size_t sz = 4096;
const std::size_t &szRef = sz;
some_opaque_func(szRef);
if (sz != 4096) std::abort(); // cannot be optimized away unless sz is const
as there is no way to know if something obtains a mutable ref to sz down the line.In other cases like RVO, adding const is actually detrimental as it prevents the move-constructor from being selected (likewise with the move assignment operator).
Rust _needs_ to have const by default due to its aliasing model ("only one mutable ref per object") and you can't have cheap bound checks without this. But that, too, is a tradeoff (some classes of programs are hard to code in Rust)
https://cpp.godbolt.org/z/Pa3bMh9Ee shows that both GCC and Clang keep the abort when sz is not const. Add const and the abort goes away.
This, this, this.
C compilers are simple, but the C language is not, and let’s not even talk about C++.
Do I?
I would simplify the problem to not need different types or generic operations.
Or if I really need generic operations, break them down to smaller operations so you don't need to take a bunch of type parameters everywhere.
For example containers, instead of having container<T>, have the container operations return an index or 'opcode', then the user applies that to their data. The container doesn't need to know about T, void pointers or sizes, just its own internal bookkeeping stuff.
Security issues are like bad etc too, just we've heard the security spiel so many times at this point. I just think it's nicer to write most stuff in Rust.
The compiler is also relatively slow. Would Rust have been worth working with on 30+ year old hardware?
No. Only massively oversimplifying, Rust could be described as a bunch of ideas pioneered among functional languages coming back to C++, the same way Java was a bunch of ideas from Lisp coming back to C. There is very little that's truly new in Rust, it's just mixing a bunch of features that were not often together before.
> The compiler is also relatively slow. Would Rust have been worth working with on 30+ year old hardware?
What makes Rust slow to compile is largely independent of what makes it unique. A lot of text has been written about this, but the again massively oversimplified version is that had the designers cared about compile times when the language was being designed and the compiler written, you could have something that's very similar to Rust but also very fast to compile.
As I understand it, a lot of the slowness of the rust compiler comes about from llvm. And how rust and llvm interoperate. Rustc creates and sends gigabytes of stuff to llvm - which passes all of that to its optimizer. If you skip all that work - for example by running cargo check - the compiler is an order of magnitude faster.
If rust were invented in the 90s, it wouldn’t have used llvm. Rust could still have been implemented, and we’d probably have a much faster compiler as a result. But it would have missed out on all the benefits of llvm too. It would have needed its own backend to be written - which would have been more work. And the compiler probably wouldn’t have been as good at low level optimisations. And it probably wouldn’t have out of the box support for so many target platforms. At least, not from day 1.
IIRC it's a combination of technical debt from earlier in Rust's life (it's easier to generate naive LLVM IR and let LLVM's optimizer do the heavy lifting of chewing through that) and how Rust implements generics via monomorphization
> and if that can't be reduced somehow.
I believe the technical debt bit can be (and is being!) reduced by implementing optimizations and better IR generation in rustc itself. As for the monomorphization strategy, I thought I remembered reading something about how Rust technically allows for generics to be implemented via non-monomorphization strategies like type erasure/dynamic dispatch, but I can't seem to find that post/article/whatever it was now so I'm not sure I'm not making it up. That being said, there are patterns to reduce the amount of code generated (e.g., generic facade that forwards to a non-generic implementation), but those need to be manually implemented at the moment and I don't think there's significant work towards automating that at the moment.
Rust is notoriously compiler-intensive. That wouldn't have been tolerated in the early PC era. When you needed fast compilers that "worked on my machine" and should work on yours. Ship it.
We did, it was called OCaml. If we'd had any sense we'd've rewritten all our systems code in it. But since C had bigger numbers on microbenchmarks, no-one cared.
So the answer is no, because humans’ collective expertise of programming language theory simply isn’t enough in 1990, unless Rust developers independently invented such features instead of copying them from GHC Haskell.
I submit that those advanced features are at most a tiny fraction of why projects like OP are seeing benefits from moving to Rust. E.g. I wouldn't be at all surprised if this Rust on Android project isn't using type families at all, or is using them only in an incidental way that could be replaced without significantly compromising the benefits.
Now if Rust did not have such language features maybe it would have implemented iterators very differently. Current Rust iterators are similar to Java iterators, and in Java, iterators themselves have a type parameter, rather than having an associated type inside the iterator trait.
Half of useful things to do are impossible or plain cumbersome to write in rust given the semantics and constraints of the borrow checker. Try to write self referential structures in rust and you'll have a more nuanced opinion.
Feel free to use unsafe {} when you need it, though.
They compare something new, which rewrite existing stuff (not only but still) with some decades-years-old cruft
In they new code, they know what they want
They can also start with state-of-the-art unit testing that may not exist in the early 2000
So .. yeah, those numbers ..
That rust is saner than c++ is a given anyway :)
Large C++ codebases have the same problems that large codebases have in any language: too many abstractions, inconsistent ways of doing things, layers of legacy. It comes with the job. The difference is that in C/C++, hard-to-read code also means hard-to-guess pointer lifetimes.
It doesn’t follow that anyone else, or the majority has to follow then. But that’s predictably exactly what veteran rustafarians are arguing in many comments in this thread.
[1] Pointers getting passed all over the place, direct indexing into arrays or pointers, C-style casts, static casts. That (PVOID)(UINT_PTR) with offsetting and then copying is ridiculous.
To a degree that users might want to even exploit such flaws to unlock their phones.
Aside from that. Sure, the constraints of Rust do solve these kinds of problems.
They made an earlier report where they found out that older C/C++ code has actually a lot less new vulnerabilities compared to new code, so I guess here they are comparing to new C/C++ code to get the higher ratio, meaning the comparison should actually be apples-to-apples.
Do you really believe that "they're not actively looking for memory safety issues in Rust" is (1) true (at least outside of Google, there is actually a ton of security work done specifically targeting just the unsafe blocks, since those are obviously where the memory safety issues lie) or (2) could possibly be responsible for a literal thousandfold reduction in memory safety issues? Remember that the Rust code is often integrated with C++ code--there is not necessarily a way to just test the C++ part even if you wanted to. Additionally, Google has explicitly prioritized code that interacts with untrusted data (like parsers and networking code) meaning it's likely to be easier to fuzz most of this Rust code than most new C++ code.
Also remember that, again, there are mechanized proofs of memory safety for a large subset of the safe portion of Rust, which constitutes 96% of the code under consideration here. The rate of memory safety bugs would have to be 25x as high per LOC in unsafe Rust code as in C code for the number of vulnerabilities to match. It would be far more shocking if we didn't see a dramatic reduction. Google is empirically demonstrating that the observed memory safety bugs per line of unsafe Rust is actually far lower than per line of C, but my point is that even if you think that is the result of bias or them not applying the same scrutiny to Rust code (something that is certainly not true of Rust vs. C code in the wild), the effect of this underrepresentation cannot possibly explain most of the reduction they observe.
Google deployed numerous state of the art mitigations prior to adopting Rust and still found that 70% of their CVEs were due to memory safety issues--your assertion that they are engaged in motivated reasoning and just wanted Rust to work out is pretty ill-founded. In fact when I worked for Google prior to Rust's release, they were strongly averse towards adopting any new language and believed that good engineering practices, automation, and a rigorous review process always outweighed the benefits of adopting a new language past their core ones, whatever its purported reliability or performance benefits. Security researchers are highly skeptical as a rule of these sorts of claims and have a lot of say at Google. They themselves changed their minds based on this sort of internal evidence.
I agree that skepticism is warranted, because we are constantly being sold things by industry. At a certain point, though, when the effect size is massive and persistent and the mechanism extremely clear, that skepticism (not in general, but of a particular claim) becomes the unscientific position. We are well past that point with Rust wrt memory safety.
The thing is with Rust, you know where to look for memory safety issues: the unsafe blocks. C and C++? GLHF that's your whole codebase. As they mentioned, you don't opt-out of all of Rust guarantees by going the unsafe route. Of course you can ditch them, but that'll be hugely visible during code review. Overall, you can be much more confident saying "yup there's no bug there" in Rust than in C or C++.
It's fair to point this out and worth the mention. Still, I'd like to think that the engineers behind this can at least gauge the benefit of this endeavor with some accuracy despite the discrepancy in available data, and stating the data that is available only makes sense.
"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."
Which means they had a pretty poor code base. If they had spent more time on engineering and less time on features that are canceled after 12 months anyway, they could have written better C/C++.
And for a large juicy target like Android, that won’t be good enough to stay ahead of the attackers long term.
Of course, tools like Fil-C or hardware-based security might make Rust vs. C or C++ moot.
Edit: your comment makes a good point. Shame that trigger-happy (c)rustaceans are downvoting everything in sight which is not praising this PR piece disguised as a technical blogpost.
I will note that developers also feel more productive in rust. That's why they migrate existing things over to it even when it may not be beneficial for security.
Of course, I am exaggerating a bit - and I am not even that experienced with Rust.
But after coding with Ruby, JS/TS and Python - it feels refreshing to know that as long as your code compiles, it probably is 80-90% there.
And it is fast, too.
All that fighting with the compiler is just fixing runtime bugs you didn’t realize were there.
I'd wager my production Rust code has 100x fewer errors than comparable Javascript, Python, or even Java code.
The way Result<T,E>, Option<T>, match, if let, `?`, and the rest of the error handling and type system operate, it's very difficult to write incorrect code.
The language's design objective was to make it hard to write bugs. I'd say it succeeded with flying colors.
I found that at some point, the rust way kinda took over in my head, and I stopped fighting with the compiler and started working with the compiler.
I’ve made this mistake in TS more times than I’d like to admit. It gives rise to some bugs that are very tricky to track down. The obvious ways to avoid this bug are by making everything deeply immutable. Or by cloning instead of sharing. Both of these options aren’t well supported by the language. And they can both be very expensive from a performance pov. I don’t want to pay that cost when it’s not necessary.
Typescript is pretty good. But it’s very normal for a TS program to type check but still contain bugs. In my experience, far fewer bugs slip past the rust compiler.
Rust is advertised as having fearless concurrency. That's true, but not that important as concurrency is not that common. What's important to everyday programming is Rust provides fearless mutability. The fearless concurrency you get with that is just a bonus.
Fearless mutability provides Rust the same safety as a functional language in a without the speed or space cost. IMO, it's Rust's true secret sauce.
Also, many built in functions do not have sufficient typesafey like Object.entries() for instance
Seeing a deserialization error immediately clues you in that your borders are not safe. Contrast that with TypeScript, where this kind of issue can lead to an insidious downstream runtime issue that might seem completely unrelated. This second scenario is very rare in other languages.
When you call a REST API (or SQL query for that matter), how does it ensure that the data coming back matches the types?
TS allows you to do parse the JSON, cast it into your target type, done (hiding correctness bugs, unless using runtime verification of the object shape, see sibling comment). Does Rust enforce this?
I wouldn’t use it server side or for a client application that doesn’t run in a web browser. That’s not its place, for me.
But I will 100% reach for it every time if I need to run in a JavaScript environment.
Despite all pluses on the blog, NDK only supports C and C++ tooling, same on Android Studio, and it is up to the community to do the needful work, if anyone feels like using Rust instead.
I could see the latter, although I'd still question whether they should be special cased in terms of a Rust dependency compared to bindings being hosted on crates.io.
Or maybe they should ship scripts that shell out to an existing Rust toolchain.
https://developer.android.com/ndk
I expect the whole Rust build process being part of Android Studio, including mixed language debugging between Java, Kotlin and Rust.
I expect all NDK APIs to have Rust bidding crates.
I expect that Android developer forums also care to support devs using Rust.
And anything else that I forgot to mentioned, that is provided for Java, Kotlin, C and C++.
[1] https://github.com/android/ndk-samples/tree/main/endless-tun...
I do agree the NDK team is rather small.
The point is about the official support for using Rust exactly for the same use cases.
But if you stick it out, as Google has, the dividend is that more often than with other languages, you are not paying these costs continually but instead reaping dividends on the long run.
First of all, Rust has the Haskell-like property that (as long as the logic is sound) if your code compiles, it usually runs just fine. This is why testing speeds up, because all of the edge cases that are explored during testing were already accounted for by the compiler.
It also translates into easier refactoring, where you can make sweeping changes in the codebase and feel confident that you can put it all back together again.
And then there's the fact that the programs themselves are fast. How many times has uv been brought up here and the #1 remark people have is "wow it's so fast!". Fast is a feature, and your users benefit from it every time they run your code.
It's hard to find that nexus of features in other languages. Usually they are just as fast and hard to write as Rust, without the safety guarantees. Or they are just as safe as Rust, but without the speed. And that's why Rust has hit a sweet spot where other languages can't quite get it.
It's so easy to bake in proofs/invariants into types, yet you still retain control of the memory model.
One of the main features of Rust is the community, there are so many great packages
Something that will replace/build on Rust in the future is a language based on Two Level Type theory, where you have zero cost abstractions with a language that can do full dependent type theory
I think that something like this is the endgame practical programming language
Like for example, how many ways are there to initialize a variable in C++? Which are you supposed to use?
This was the same argument for Java, which is memory safe, fairly strict in terms of ownership.
The fact is, Rust addresses only one memory safe thing, and that is double free. If you don't understand why that is, you probably shouldn't talk about memory safety.
The dividends never get there if you don't ever run into this.
>And then there's the fact that the programs themselves are fast. How many times has uv been brought up here and the #1 remark people have is "wow it's so fast!"
This is a vibe at best. The speed difference is surely there. But it makes very little difference when there are much slower things in the entire workflow, like pulling things from the internet.
Basically, Rust is a good choice for a small subset of things. Android happens to be one of them, because a) you need native code performance, b) you have multiple teams working on many services and c) you have a somewhat closed ecosystem where you control a lot of the low level things. Because of all of this, double frees are a real threat and can pop up as you are passing data around without strict checks.
How does Rust not address use after free?
There is a reason why most vulnerabilities these days are either higher level logic bugs, or things that require code execution on the machine.
Have fun justifying that Rust is "also" unsafe, with the right tools you can achieve the same in C++, if you're a great dev you can do even better, etc.
It can be annoying to write "safe" code, but once it meets a certain standard I can be confident in multithreaded applications I write.
I would like to use rust to write android apps. I don't really like the whole android studio java thing.
I expect that Google is using neither of these for most of their own code, but rather their own build system (which I think is the same between the languages).
I absolutely agree if you aren't Google though.
If I were to go to another company I’d promote using either of the above.
Proprietary code uses the internal version of Bazel: https://bazel.build/
That is an understatement. I can't think of a build system that has spawned more attempts to find something better than CMake has.
There have been so many people trying to make their own C/C++ build system and/or package manager out of sheer spite for CMake that it's frankly hard to keep track.
In fairness to them and to CMake, it's not a simple problem to solve. To truly know CMake is to wish you didn't, that way someone else would have to maintain it.
For me the ideal syntax is C/Go, just to be clear what I like.
But I agree that the tooling that cargo introduced is a breath of fresh air in a world dominated by huge makefiles, libraries copied in the repository (I know, there is Conan, vcpkg etc)...
I’m sorry if this comes across as dismissive, but I find it hard to take people seriously with complaints about syntax like this. Learning new syntax is really easy. Like, if you’re familiar with C & Go, you could probably learn all the syntax of rust in under an hour. The only surprising part of rust’s syntax is all the weird variants of match expressions.
Rust has some surprising semantics. Like how lifetimes work (and when you need to specify them explicitly). That stuff is legitimately difficult. But learning that if statements don’t need parenthesis is like - seriously whatever dude. If you want to spend your career never learning new stuff, software isn’t for you.
I picked up objective C about 15 years ago. The only thing most of my friends knew about it was that it had “that weird syntax”. It took no time at all to adjust. It’s just not that hard to type [] characters.
But if I was working in C++ and had a choice of C++ or Rust, I’d go Rust based on this.
Distributing Rust software is the pain that it is mostly because of how Cargo works. It’s pretty much impossible to sanely distribute something that isn’t a headache for downstream to consume.
"Absolutely awful" strikes me as wild hyperbole -- you also meant it this way as well, right? What toolchains are not absolutely awful in your mind?
Cargo isn't perfect by any stretch of the imagination -- there are a few common complaints that people have and a bunch of sharp edges (most of which have a github issue that has been open for years), but... "absolutely awful" has to be hyperbole.
But that's just not how Rust works: it's trying to fit a square peg in a round hole, and it isn't Cargo's fault that you have trouble with it.
I’ve found it a joy to use compared to CMake and friends. How does it make it harder to consume something downstream? Seems easy enough to me - just share the source crate.
Are you trying to distribute pre compiled code or something like that? I can see how that would be harder - cargo doesn’t really support that use case.
How would you improve cargo?
Cargo is a blessing for any source-available project. All bundled up, a `cargo build` away. Because don't you dare say CMake or autotools are better, that's just the stockholm syndrome kicking in because you're familiar with it.
Seriously, how a CMakeLists.txt can even be compared to a Cargo.toml file? One is imperative full of arcane conditions everywhere filled with boilerplate, while Cargo.toml is a declarative manifest of the package?
Though there is one very sore point when distributing software, and that is for distribution package maintainers, because the whole ecosystem has been built around the C model and dynamic linking. That is not even the fault of cargo, since Rust's ABI is not stable thus dynamic linking would not work most of the time. Another thorn is generic stuff, which needs to be monomorphized, and as such don't work with dynamic linking (without Box<dyn>); C++ actually has the same issue and is why there are so many "header only" libraries for it.
Personally I’m relieved that we’re starting to see real competition to the C & C++ duopoly. For awhile there all the new languages were GC, and paid for their shiny features with poor runtime performance. (Eg java, C#, Ruby, Python, lua, go, etc etc)
Rust is a fine language. Personally I can’t wait to see what comes after it. I’m sure there’s even better ways to implement some of rust’s features. I hope someone out there is clever enough to figure them out.
Then there are enough industry standards that are defined for C and C++, where Rust isn't even visible.
(doesn't mean it's not an improvement on C++)
All the ways to coerce and poke the implementation of what should be safe constructs to produce unexpected garbage - and people spending time fixing the issues because they are treated as bugs.
It’s like the best possible advertisement for ”we enable soundness and correctness for all your programs.”
https://github.com/rust-lang/rust/issues?q=state%3Aopen%20la...
That being said, it would be pretty easy to implement some pointer semantics even in C that can do 95% of what Rust does.
Making a language with memory-safe pointers isn't hard. Making a language with memory-safe pointers that doesn't rely on sandboxing, a virtual machine, or other dynamic checks which produce runtime overhead--thereby disqualifying one from being considered for this domain in the first place--is nontrivial.
Plenty of people don't write Rust for additional memory safety, they write Rust because the features provided by it is overall very balanced & encourages developer to write code which handles almost all edge cases.
Which is more that rust isn’t that safe in my mind, it’s that bugs are that prevalent. I never would have guessed that.
That 4x rate is very impressive too.
Great seeing all this data from a large big complicated codebase.
The way it should work is that before even writing code, you design a modular acceptance system that runs full suite of tests or a subset based on what you are working on.
This is essentially your contract for software. And on a modular level, it means that it scopes down the contracts to the individual sub systems. And things like memory and cpu runtime constraints are a part of this.
If you have this, you basically replace what the Rust compiler is doing for you with tests. Memory leaks are caught. However, as a benefit, you also can verify changes in the dev cycle with things like performance degradation, all in the same system.
Getting rid of a whole host of bugs due to the compiler is a big deal because you won't have to design this extra acceptance system or deal with keeping an entire organization disciplined by it. If you can solve this seamlessly I think that's an interesting product that others would be very interested in.
Sometimes. It depends on what you’re working on.
Part of the fun challenge in writing software is that the act of programming can teach you that you’re wrong at every level. The syntax can be wrong. The algorithm you’re implementing can be wrong. The way you’re designing a module can be misguided. And you might be solving the wrong problem entirely! Like, maybe you spend weeks adding a feature to a game and it makes the game less fun! Oops!
Tests formalise beliefs about what you want your code to do, at some level of abstraction. But if those beliefs turn out to be wrong, the tests themselves become a headwind when you try and refactor. You want those early refactoring to be as easy as possible while you’re learning a problem space.
Now, some programs don’t suffer from this as much. If you’re implementing a C compiler or drop in replacement for grep, you have some clear acceptance tests that will almost certainly not change through your project’s lifecycle.
But not all problems have clear constraints like that. Sometimes you’re inventing a programming language. Or writing a game. Or making a user interface. In my opinion, problems that are fully constrained from the start are some of the least interesting to work on. Where’s the discovery?
Anyway Google has all of that, and yet still finds this improvement.
If you've actually written considerable amounts of Rust and C++, these statistics don't require justification. In my opinion it's completely expected that Rust code is easier to write correctly.
For example: folks are more likely to rewrite stuff that is well-understood, and stuff that is well-understood is going to have shorter review times and lower rollback rate.
That gnarly horrid mess that only a few greybeards grok and has massive test coverage, a long tail of requirements enforced by tests and experience, and a culture of extreme rigor? Longer reviews, more rollbacks, and less likely to be rewritten.
Personal experience also provides a compelling reason, my experience is absolutely that people are more inclined to rewrite the things that are causing trouble in a new language.
It's not a blinded randomly controlled trial of course, it's observational data. You can't be completely sure there isn't a confounding factor that explains the data, but it seems far more likely than not that it is a real effect.
Bjarne's C++ promised that if you use this instead of C you won't have these problems. The problems persisted of course. Then it was well you need to use standard C++ 98 not that crap pre-standard C++ you've been doing, once you adopt C++ 98 the problems will subside. Then it's you need "modern" C++ 11, of course you've got problems, that's because you used C++ 98, use this "modern" C++ instead.
By around 2020 they started to say the "modern" C++ 11 wasn't up to it, you need to write "contemporary" C++ 20 or better.
What was it George W Bush told us? "Fool me once, shame on...shame on you. Fool me...you can't get fooled again".
I'd say that this is likely the most likely to be rewritten actually, because high test coverage is a massive enabler in such a rewrite, and because having a project that “only a few greybeards grok” sounds like a big organizational liability.
That being said, and while I'm pretty convinced that Rust bring massive benefits, I agree with you that these measurements shouldn't be taken as if it was a rigorous scientific proof. It's more of one additional anecdotal evidence that Rust is good.
But that means it's likely to be the worst kind of science:
- Group of people agree that Rust is good. This is a belief they hold.
- Same group of people feel the need to search for argument that their belief is good.
- The group does "science" like this.
And then the rest of us have a data point that we think we can trust, when in reality, it's just cherry picked data being used to convey an opinion.
Calling what Google did here "science" and cherry picked is quite a disservice. It's observational data, but do you have any objection to the methodology they used? Or just (assumed?) bad vibes?
It would be interesting to group changes by line-deletions, say to indicate rewrites (and size of them)
I find this surprising, isn't Wuffs[1] (also made by Google) an even better fit for this particular use-case? (It has compile-time spatial memory safety, where Rust has compile-time temporal safety but runtime spatial safety, with bound checking).
Obviously for general-purpose system programming, Rust is a no-brainer and I'm happy to see Google pursuing their rustification of Android.
Which isn't to say that it shouldn't be adopted (having not used it I really don't know), just that it's not surprising that it's having difficulty gaining traction.
If you check Wuffs repo, you'll see benchmarks very favorably comparing to rust implementations.
And it's not surprising, wuffs is to spatial safety what the borrow checker is to temporal safety. And regarding spatial safety rust is kind of like where C++ is in terms of temporal safety: it has the choice between unsafe or runtime check hopping that a large fraction of them will get eliminated by the compiler.
I do hobbyist level gamedev in my spare time and found bevy to be a bit too much for the things I want to do.
In any case, I'm glad we're seeing more and more evidence and case-studies of why "rewrite it in Rust" isn't just a meme.
It's all nonsense, but it would be hilarious if it weren't so ignorant.
Multics got an higher security score than UNIX, thanks to PL/I.
During the USENET flamewar days, they used to call programming with straightjacket languages.
Also note how proudly they keep digging out Brian Kerninghan complains against Pascal, that disregard the dialects have taken out those issues, and that while Pascal was designed for teaching, Modula-2 was already available, taking care of those pain points, designed for systems programming.
How is any of that wrong?
In other words, they're upset that a new thing isn't popular so they're trying to think of any argument against it, but none of their arguments are relevant. Yes, you can still write bugs in Rust; of course you can. What you can't do is write memory safety bugs in Rust, which are a huge proportion of security bugs that occur. Rust gives you a massive decrease in attack surface automatically.
This is ignoring the ecosystem, which is full of better tooling, better library packaging, better testing, and just in general an overall better language, but instead of trying to argue the language on its merits they're trying to argue that it's not perfect so why bother.
I've also heard the same arguments about C++; 'anything you can do in C++ you can do in C!', which is technically true but ignores the fact that if I want to do something C++ does it usually makes more sense to use C++ to do it rather than e.g. trying to hack the concept of objects, private methods, templates, etc. into C myself.
2. You can still write bugs in Rust but the point is you are far less likely to.
Chromium: Parsers for PNG, JSON, and web fonts have been replaced with memory-safe implementations in RustBinder kernel driver: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/lin...
Media codecs: https://www.androidauthority.com/android-16-in-process-softw...
> Rewriting SymCrypt in Rust to modernize Microsoft’s cryptographic library
https://www.microsoft.com/en-us/research/blog/rewriting-symc...
I think they're trying to avoid rewriting things for no reason though. The things being rewritten tend to have a history of security problems or other issues that would be cause for a rewrite even if it wasn't in Rust.
That however is a very niche case where Rust is applicable. The anti-rust people (like me) aren't saying that Rust is bad. We are just arguing against its adoption for everything.
When you see shit like "[...] should be rewritten in Rust because memory safe", it shows that people have no idea what memory safety even is. There is this dumb belief stemming from lack of proper CS education that any code you write can just randomly have memory safety issues.
The downsides of Rust is that its ownership semantics are often cumbersome to write, which slows down development. Rust is also still evolving because of the stuff that happens under the hood. And for a lot of things, where network latency is dominant and cpu cycles are spent sleeping waiting for responses to come back, you don't need natively compiled code in lieu of python or node that are way more flexible and faster to develop in.
So in most cases, Rust is not applicable, when you can write perfectly memory safe code faster.
There is this dumb belief stemming from lack of proper CS education that any code you write can just randomly have memory safety issues.
This is effectively true in C and C++ though. Show me a nontrivial project in either of those languages that has never had a memory safety issue and I'll show you a project that doesn't look at quality. Even SQlite doesn't meet this bar, despite incredibly skilled programmers and an obsessive commitment to quality.I mean, the linux kernel is a pretty good example. Static analyzers and things like valgrind exist for a reason.
I sense a lack of statistical education here.
lol. this take is hilarious in the face of the article you are commenting on. holy cognitive dissonance.
> The downsides of Rust is that its ownership semantics are often cumbersome to write
skill issue
Lol, this is actually very ironic considering Rust is handholding you because you don't have the skills to write memory safe code.
Like I said in my other posts, Rust makes sense in very niche situations. The article just proves that it works for the niche case where its applicable. That doesn't mean Rust automatically wins.
Then in the next graph, showing "Rust" and "C++", we see that the amount of C++ code written in 2022 actually increased, with rust not really having gained any significant momentum.
How can one possibly square those two pieces of data to point at rust somehow fixing the "memory safety vulns"? Somehow an increase in C++ code led to a decrease in the amount of both "New Memory Unsafe Code" and "Memory safety Vulns".
Also "this approach isn’t just fixing things, but helping us move faster." is an AI red flag.
The first graph considers <memory unsafe> vs <memory safe> languages, while the second graph considers C++ vs Rust. There's more languages than just those two in the first graph.
Moreover the first graph is in percentage terms, while the second graph is in absolute terms.
In 2022 it appears a bunch of memory safe non-rust code was added. Java/python/...
> Also "this approach isn’t just fixing things, but helping us move faster." is an AI red flag.
That's a perfectly human phrasing lol.
Crucially Rust is a very pleasant developer experience. Out of the box tooling is smoother, the compiler diagnostics are much better than peer languages†, the community are nicer, and so on. When you wrote safe Rust which compiles you get software that does what you wrote and not something else, which seems like a very basic thing to ask for but neither C nor C++ can do this. People respond well to a more pleasant environment.
† I wrote the one where if you write 'A' (the Unicode character capital A) but actually meant the ASCII byte 65 the diagnostic suggests writing b'A' instead rather than just telling you that what you wrote is a type mismatch.
The code base contains Kotlin and Java as well
Who do you think AI learned it from