Hacker News new | ask | show | jobs
by shevy-java 2 days ago
C and C++ are kind of losing out to Rust right now.

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.

4 comments

> but Rust is pushing into domains where C and C++ dominated in the past.

I think it's also a big sign that the linux kernel adopted rust and not c++. (only for small parts but still)

A not inconsiderable part of why is that Rust for Linux did the work.

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.

> their proposal usually begins by proposing that it "should" be possible to just compile Linux as C++ software

That has already been done in the past. Quoting the FAQ:

"[...] the kernel was once modified to be compiled under g++. That lasted for a few revisions. People complained about the performance drop. It turned out that compiling a piece of C code with g++ would give you worse code. It shouldn't have made a difference, but it did. Been there, done that."

Yet the C compilers they use are written in C++.

It was mostly a Linus issue, and not wanting to fix what were the root causes of the regressions.

I think most people didn't really care enough because if they knew C++ and they cared enough, they could still effectively contribute to the kernel.
Honestly this just makes it sound like C++ people either didn't really care about it in practice or just were weirdly insistent that they get to decide how to integrate the language into an existing project. At best, it's just another instance of the claims that C++ could totally do everything Rust does (but somehow still never seems to in real life), and at worst it just kind of reflects poorly on the social skills of the people who tried to push it.
Too busy contributing to Symbian, Windows, macOS, BeOS...
Sure, not caring about contributing to Linux in practice is valid, but at that point it would make more sense just not to argue about the aptness of C++ for integrating into Linux at all then if no one ever legitimately tried. My point is that the parent comment is trying to have it both ways by arguing that C++ totally could be integrated into the Linux kernel as a dismissal of the real-world case of Rust being integrated but then ignoring the actual real-world case of C++ not getting integrated into the kernel.

At a higher level, I've noticed a long-term trend where dismissals of Rust from C++ proponents have continued to grow increasingly abstract; the line of reasoning basically seems to be that how Rust is used in practice can be ignored as long as there's a sufficient theoretical argument for C++ being able to do the same thing. This is a remarkable retreat from the previous objections to Rust being impractical compared to C++ which I'd argue is itself evidence of the ground that Rust has gained in the past several years. It seems to have happened without the C++ community noticing though, which at least in part seems to come from some cognitive dissonance; in your two replies to my comments in this thread, you demonstrated this yourself by arguing on pragmatic grounds about how C++ is used in practice in this comment but then rejecting criticism of C++ in your other comment by asserting that a "recipe" for memory safety is enough to dismiss concerns about how pretty much no real-world project actually achieves this.

My (obviously biased) perception is that the shortcomings of Rust tend to be pretty widely agreed upon by the experts in the community and mostly dismissed by people who honestly aren't nearly as experienced in the language, whereas with C++ the most expert members of the community seem prone to handwaving away concerns that deserve a lot more attention.

Because Linus, plenty of other OSes have adopted C++ on their internals.
I agree about Rust gaining ground but using the argument that it got 10% faster due to Rust is not really that useful.

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.

I don't think it's due to Rust being inherently faster, but there have been plenty of documented cases of being able to take better advantage of concurrency due to the guarantee of no data races. Trying to do the same in C++ would expose new risks to UB, at which point you're just kind of back to the same safety argument that presumably motivated the move to Rust in the first place
I think the difference in languages that allows for faster performance is that Rust does a good job of surfacing expensive operations and it makes defensive programming less of a requirement.
> 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.

Until Rust has equal meta-programming support to C++ it's always going to be "slower". That's why people always say this because it's always true there is nothing Rust can do C++ can't but there is quite a few things you can do in C++ but not in Rust.

Realistically the difference doesn't matter much and if you're writing code that must be as fast as possible your writing unsafe Rust that looks a lot more like C/C++ then anything Rust.

> Until Rust has equal meta-programming support to C++ it's always going to be "slower".

What metaprogramming does C++ have that rust is lacking?

If you need more than traits + generics, rust also has proc macros. Proc macros are essentially portable compiler extensions. They take in a stream of symbols from the user's program at compile time and emit rust code that gets passed straight to the compiler. You lose out on syntax highlighting and they make compilation slower. But macros are essentially compile-time code gen. They work great. In rust, you can do things like JSX at compile-time without any special compiler support. (See: leptos.)

> Realistically the difference doesn't matter much and if you're writing code that must be as fast as possible your writing unsafe Rust that looks a lot more like C/C++ then anything Rust.

I agree that the difference is small in practice. Good rust often does look a lot like C - with plain structs everywhere and lots of global-ish scoped functions.

But I don't agree about unsafe. I've spent some time porting well optimised code from C to rust. I generally find I need far less unsafe code than I expected. I ported a ~500 line skip list implementation from C to rust a few years ago. I think my rust code ended up using just 2 unsafe functions. The rest of the code didn't need any unsafe at all.

My skip list was a monster to debug in C because most logic bugs ended up corrupting memory. As a result, a bug in one function caused crashes in far away code. In rust, debugging was much easier. There wasn't any "spooky action at a distance". And that let me reason about the code much more easily. As a result, once I got it working I ended up adding a few more optimisations in rust that I was too overwhelmed to write in C. The rust code is now ~2-3x faster.

If you're interested:

https://github.com/josephg/jumprope-rs#benchmarks

C code is here: https://github.com/josephg/librope

> What metaprogramming does C++ have that rust is lacking?

Compile time execution, and compile time reflection, with the same syntax.

Proc macros are still a kludge having to depend on syn crate, and some stuff used to depend on nightly, is that still the case, I don't keep track?

Additionally type specialisation, and explicit templates.

Proc macros haven't depended on nightly things in a very, very very long time.
> there is nothing Rust can do C++ can't but there is quite a few things you can do in C++ but not in Rust

The point the parent comment is making is that this doesn't really matter if no one actually does do these things in C++. It's absolutely wild to me how quickly the arguments in favor of C++ instead of Rust have reversed in about a decade; people used to argue that the benefits of Rust were all theoretical and in practice people who were used to C++ could write it perfectly fine without safety issues, and now it's somehow that the theory that gives C++ the advantage and we don't need to care about whether those supposed advantages ever actually exist in practice.

> Until Rust has equal meta-programming support to C++ it's always going to be "slower".

I don't think that makes a lot of sense even theoretically because of e.g. aliasing, but it doesn't matter because as I said, C++ chooses to be slower, Titus gives a number of examples where we know how to do X fast, and that's how Rust does X - in theory C++ could X the same way, but none of the three C++ compilers people actually use do it, because they picked wrong and then froze their ABI and won't thaw it.

No one writing anything that needs performance cares about some standard library ABI issues. Rust already has warts from bad API designs that constrains performance and they are unlikely to ever be fixed even with new editions. Rust will continue to pick up baggage as basically every language has done.

Aliasing has yet to provide any real benefit for Rust and a hell of a lot of issues. Maybe one day it will be a big win but realistically anyplace that aliasing matter c/c++ will just drop __restrict on it.

> Rust already has warts from bad API designs that constrains performance and they are unlikely to ever be fixed even with new editions.

Like what?

> Aliasing has yet to provide any real benefit for Rust and a hell of a lot of issues.

Yeah, the performance wins so far are quite small. But rust's noalias-by-default did unearth a whole lot of latent bugs in LLVM. Even if you don't care about rust, its great that rust led LLVM to track down and fix these bugs. They affected C/C++ code too.

> realistically anyplace that aliasing matter c/c++ will just drop __restrict on it.

Is there a way to tell? When I'm writing C, I have no idea if using restrict will help other than staring at the assembly. (Or just trying it). I'm also leery of using restrict in C because its so hard to audit callers. How do you know when restrict is safe?

>ColdString and CompactString, which are way better than what's provided in C++

Could you elaborate on that?

Sure, to simplify lets assume a 64-bit CPU (this all works for 32-bit but that's less common these days and the actual numbers are different)

C++ std::string can contain up to 15 (other popular implementations) or 22 bytes (libc++ from Clang) of inline text, and the data structure itself is either 24 bytes (Clang again) or 32 bytes of storage. Here's Raymond Chen: https://devblogs.microsoft.com/oldnewthing/20240510-00/?p=10...

CompactString is 24 bytes of storage with all 24 bytes as potential inline text. When the 24 bytes are valid UTF-8 text, then that's the content of the CompactString e.g. "https://example.org/cool", if they aren't the last byte will be invalid UTF-8, and this signals whether some of the other 23 bytes were inline UTF-8 (and if so how many) or whether they should be interpreted as a pointer, size and capacity.

ColdString is a radically different idea, it's 8 bytes of unaligned storage and it's one of three things: 1. 8 bytes of UTF-8 text, as before we can tell by whether it's valid UTF-8 text or 2. 0-7 bytes of UTF-8 text, prefixed by an invalid UTF-8 byte telling us how many of the remaining bytes are text or 3. An encoded pointer to a length-prefixed data structure, signalled by the presence of the UTF-8 continuation marker bits which should never be present in the first byte of a string.

I really like ColdString because it's so much in the "use the whole buffalo" spirit of these modern safe yet high performance types. UTF-8 has what are called "overlong prefixes" because it was invented before Unicode decided it would never grow beyond U+10_FFFF and these are often just a useless impediment, but ColdString uses those prefixes.

Thanks!

How do CompactString/ColdString compare to std::string implementations performance-wise? From the looks of it, they must be somewhat slower than C++ strings

I do not have hard numbers - however keep in mind that practical "performance" also includes memory bandwidth and total RAM, this is especially a consideration for the ColdString type - a billion ColdStrings is 8GB of RAM, but a billion MSVC std::string needs 32GB of RAM. Rust's std::string::String is of course much faster than any of the std::string implementations because it never has the SSO case to consider - but for non-empty strings it's also more memory bandwdith and RAM needed.
>"are kind of losing out to Rust right now"

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

> C and C++ are kind of losing out to Rust right now.

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.