This technical blog post compares C++ and Rust programming languages, analyzing type safety and compiler-enforced error prevention through practical code examples. The content has minimal engagement with human rights themes, with only structural signals of free expression evident through the blog's allowance of diverse and critical reader commentary.
Yes, Rust is better. Implicit numeric conversion is terrible. However, don't use atoi if you're writing C++ :-). The STL has conversion functions that will throw, so separate problem.
The one thing that sold me on Rust (going from C++) was that there is a single way errors are propagated: the Result type. No need to bother with exceptions, functions returning bool, functions returning 0 on success, functions returning 0 on error, functions returning -1 on error, functions returning negative errno on error, functions taking optional pointer to bool to indicate error (optionally), functions taking reference to std::error_code to set an error (and having an overload with the same name that throws an exception on error if you forget to pass the std::error_code)...I understand there's 30 years of history, but it still is annoying, that even the standard library is not consistent (or striving for consistency).
Then you top it on with `?` shortcut and the functional interface of Result and suddenly error handling becomes fun and easy to deal with, rather than just "return false" with a "TODO: figure out error handling".
Amazing example of how easy it is to get sucked into the rust love. Really sincerely these are really annoying parts of C++.
The conversation function is more language issue. I don’t think there is a simple way of creating a rust equivalent version because C++ has implicit conversions. You could probably create a C++ style turbofish though, parse<uint32_t>([your string]) and have it throw or return std::expected. But you would need to implement that yourself, unless there is some stdlib version I don’t know of.
Don’t conflate language features with library features.
And -Wconversion might be useful for this but I haven’t personally tried it since what Matt is describing with explicit types is the accepted best practice.
It's a shame Rust doesn't have keyword arguments or named tuples to make handling some of these things easier without Args/Options structs boilerplate.
There is '-Wconversion' to catch things like this. It will however not trigger in this specific case since g++ assumes converting 1000.0 to 1000 is ok due to no loss in precision.
Quantity(100) is counterproductive here, as that doesn't narrow the type, it does the opposite, it casts whatever value is given to the type, so even Quantity(100.5) will still work, while just plain 100.5 would have given an error with '-Wconversion'.
Coming from python (or Common Lisp, or...), I wasn't too impressed. In Python I normally make args for any function with more than a couple be keyword arguments, which guarantees that you are aware of how the arguments are being mapped to inputs.
Even Rust's types aren't going to help you if two arguments simply have the same types.
What sold me on Rust is that I'm a very bad programmer and I make a lot of mistakes. Given C++, I can't help but hold things wrong and shoot myself in the foot. My media C++ coding session is me writing code, getting a segfault immediately, and then spending time chasing down the reason for that happening, rinse and repeat.
My median Rust coding session isn't much different, I also write code that doesn't work, but it's caught by the compiler. Now, most people call this "fighting with the borrow checker" but I call it "avoiding segfaults before they happen" because when I finally get through the compiler my code usually "just works". It's that magical property Haskell has, Rust also has it to a large extent.
So then what's different about Rust vs. C++? Well Rust actually provides me a path to get to a working program whereas C++ just leaves me with an error message and a treasure map.
What this means is that although I'm a bad programmer, Rust gives me the support I need to build quite large programs on my own. And that extends to the crate ecosystem as well, where they make it very easy to build and link third party libraries, whereas with C++ ld just tells you that it had a problem and you're left on your own to figure out exactly what.
I see an article about how strict typing is better, but what would really be nice here is named parameters. I never want to go back to anonymous parameters.
This seems a big silly. This is not a language issue. You can have a C++ library that does exactly all the things being shown here so that the application developer doesn't worry about. There would no C++ language features missing that would accomplish what you're able to do on the Rust side.
So is this really a language comparison, or what libraries are available for each language platform? If the latter, that's fine. But let's be clear about what the issue is. It's not the language, it's what libraries are included out of the box.
The C++ code I write these days is actually pretty similar to Rust: everything is explicit, lots of strong types, very simple and clear lifetimes (arenas, pools), non-owning handles instead of pointers. The only difference in practice is that the build systems are different and that the Rust compiler is more helpful (both in catching bugs and reporting errors). Neither a huge deal if you have a proper build and testing setup and when everybody on your team is pretty experienced.
By the way, using "atoi" in a code snippet in 2025 and complaining that it is "not ideal" is, well, not ideal.
Seems to make it clear C++ is just broken. That said, and I wish he'd covered this, he didn't mention if the flags he brings up would warn/fix these issues.
I don't want a C++ where I have to remember 1000 rules and if I get one wrong my code is exploitable. I want a C++ where I just can't break the rules except when I explicitly opt into breaking them.
speaking of which, according to another C++ talk, something like 60% of rust crates are dependent on unsafe rust. The point isn't to diss rust. The point is that a safe C++ with opt into unsafe could be similar to rust's opt into unsafe
All this has been known in the PL design community for decades if not half a century by now.
Two things are incredibly frustrating when it comes to safety in software engineering:
1. The arrogance that "practitioners" have against "theorists" (everyone with a PhD in programming languages)
2. The slowness of the adoption of well-tested and thoroughly researched language concepts (think of Haskell type classes, aka, Rust traits)
I like that Rust can pick good concepts and design coherent language from them without inventing its own "pragmatic" solution that breaks horribly in some use cases that some "practitioners" deem "too theoretical."
I always enjoy reading articles like this. But the truth is, having written several 100s of KLOC in C++ (i.e., not an enormous amount but certainly my fair share) I just almost never have problems with this sort accidental conversion in practice. Perhaps it might trip me up occasionally, but will be noticed by literally just running the code once. Yes, that is an extra hurdle to trip over and resolve but that is trivial compared to the alternative of creating and using wrapper types - regardless of whether I'm using Rust or C++. And the cost of visual noise of wrapper types, already higher just at the writing stage, then continues to be a cost every time you read the code. It's just not worth it for the very minor benefit it brings.
(Named parameters would definitely be great, though. I use little structs of parameters where I think that's useful, and set their members one line at a time.)
I know that this is an extremist view, but: I feel the same way about Rust's borrow checker. I just very rarely have problems with memory errors in C++ code bases with a little thought applied to lifetimes and use of smart pointers. Certainly, lifetime bugs are massively overshadowed by logic and algorithmic bugs. Why would I want to totally reshape the way that I code in order to fix one of the least significant problems I encounter? I actually wish there were a variant of Rust with all its nice clean improvements over C++ except for lifetime annotations and the borrow checker.
Perhaps this is a symptom of the code I tend to write: code that has a lot of tricky mathematical algorithms in it, rather than just "plumbing" data between different sources. But actually I doubt it, so I'm surprised this isn't a more common view.
This is actually the point where Rust starts to frustrate me a little bit.
Not because Rust is doing anything wrong here, but because the first well-known language to really get some of these things right also happens to be a fairly low-level systems language with manual memory management.
A lot of my colleagues seem to primarily be falling in love with Rust because it's doing a good job at some basic things that have been well-known among us "academic" functional programming nerds for decades, and that's good. It arguably made inroads where functional programming languages could not because it's really more of a procedural language, and that's also good. Procedural programming is a criminally underrated and misunderstood paradigm. (As much as I love FP, that level of standoffishness about mutation and state isn't any more pragmatic than OOP being so hype about late binding that every type must support it regardless of whether it makes sense in that case.)
But they're also thoroughly nerdsniped by the borrow checker. I get it, you have to get cozy with the borrow checker if you want to use Rust. But it seems like the moral opposite of sour grapes to me. The honest truth is that, for most the software we're writing, a garbage collected heap is fine. Better, even. Shared-nothing multithreading is fine. Better, even.
So now we're doing more and more things in Rust. Which I understand. But I keep wishing that I could also have a Rust-like language that just lets me have a garbage collector for the 95% of my work where the occasional 50ms pause during run-time just isn't a big enough problem to justify a 50% increase in development and maintenance effort. And then save Rust for the things that actually do need to be unmanaged. Which is maybe 5% of my actual work, even if I have to admit that it often feels like 95% of the fun.
Maybe contrarian, but imo the `Result` type, while kind of nice, still suffers from plenty of annoyances, including sometimes not working with the (manpages-approved) `dyn Error`, sometimes having to `into()` weird library errors that don't propagate properly, or worse: `map_err()` them; I mean, at this point, the `anyhow` crate is basically mandatory from an ergonomics standpoint in every Rust project I start. Also, `?` doesn't work in closures, etc.
So, while this is an improvement over C++ (and that is not saying much at all), it's still implemented in a pretty clumsy way.
It's bad if it alters values (e.g. rounding). Promotion from one number representation to another (as long as it preserves values) isn't bad. This is trickier than it might seem, but Virgil has a good take on this (https://github.com/titzer/virgil/blob/master/doc/tutorial/Nu...). Essentially, it only implicitly promotes values in ways that don't lose numeric information and thus are always reversible.
In the example, Virgil won't let you pass "1000.00" to an integer argument, but will let you pass "100" to the double argument.
Generally, I agree the situation with errors is much better in Rust in the ways you describe. But, there are also panics which you can catch_unwind[1], set_hook[2] for, define a #[panic_handler][3] for, etc.
+1, especially loved the episode from a couple months back about using AI tools in development. Really got me thinking differently about the role of AI in a developer's workflow and how software development will evolve.
The result type does make for some great API design, but SerenityOS shows that this same paradigm also works fine in C++. That includes something similar to the ? operator, though it's closer to a raw function call.
SerenityOS is the first functional OS (as in "boots on actual hardware and has a GUI") I've seen that dares question the 1970s int main() using modern C++ constructs instead, and the API is simply a lot better.
I can imagine someone writing a better standard library for C++ that works a whole lot like Rust's standard library does. Begone with the archaic integer types, make use of the power your language offers!
If we're comparing C++ and Rust, I think the ease of use of enum classes/structs is probably a bigger difference. You can get pretty close, but Rust avoids a lot of boilerplate that makes them quite usable, especially when combined with the match keyword.
I think c++, the language, is ready for the modern world. However, c++, the community, seems to be struck at least 20 years in the past.
> The one thing that sold me on Rust (going from C++) was that there is a single way errors are propagated: the Result type. No need to bother with exceptions
This isn't really true since Rust has panics. It would be nice to have out-of-the-box support for a "no panics" subset of Rust, which would also make it easier to properly support linear (no auto-drop) types.
Just create dummy wrappers to make a type level distinction.
A Height and a a Width can be two separate types even if they’re only floats basically.
Or another (dummy) example transfer(accountA, accountB). Make two types that wrap the same type but one being a TargetAccount and the other SourceAccount.
Result type still requires quite a few lines of boilerplate if one needs to add custom data to it. And as a replacement of exceptions with automatic stack trace attachment it is relatively poor.
In any case I will take Rust Result over C++ mess at any time especially given that we have two C++, one with exception support and one without making code incompatible between two.
Yes, this is one of the few things that I think was a big mistake in Rust's language design. I used to do a lot of Scala, and really liked named parameters there.
I suppose it could still be added in the future; there are probably several syntax options that would be fully backward-compatible, without even needing a new Rust edition.
Just like language shapes the way we think and talk about things, programming languages shape both what libraries are written and how. You could write anything in anything so long as it's Turing complete, but in real life we see clearly that certain design decisions at the language level either advantage or disadvantage certain types of solutions. Everyone could in theory write C without any memory issues, but we all know how that turns out in practice. The language matters.
Using your media example since I have a decent amount of experience there. Did you just use off the shelf libraries, because effectively all the libraries are written in or expose a C api. So now you not only need to deal with Rust, you need to also deal with rust ffi.
There are some places I won’t be excited to use rust, and media heavy code is one of those places…
The core of this argument taken to its extreme kind of makes the whole discussion pointless, right? All the languages can do all the things, so why bother differentiating them?
To entertain the argument, though, it may not be a language issue, but it certainly is a selling point for the language (which to me indicates a "language issue") to me if the language takes care of this "library" (or good defaults as I might call them) for you with no additional effort -- including tight compiler and tooling integration. That's not to say Rust always has good defaults, but I think the author's point is that if you compare them apples-to-oranges, it does highlight the different focuses and feature sets.
I'm not a C++ expert by any stretch, so it's certainly a possibility that such a library exists that makes Rust's type system obsolete in this discussion around correctness, but I'm not aware of it. And I would be incredibly surprised if it held its ground in comparison to Rust in every respect!
Meaning you're in a context where you have control on the C++ code you get to write. In my company, lots of people get to update code without strict guidelines. As a result, the code is going to be complex. I'd rather have a simpler and more restrictive language and I'll always favor Rust projects to C++ ones.
Sure, you can emulate some of the features and hope that everyone using your library is doing it "right". Just like you could just use a dynamic language, tag every variable with a type, and hope everyone using your library does the MANUAL work of always doing it correct. Guess we don't need types either.
And while we're at it, why not use assembly? It's all just "syntactic sugar" over bits, doesn't make any difference, right?
Why? In 2025 we have tooling available for most every editor that will annotate that information into the display without needing them present in the file. When I autocomplete a function name, all the parameters are there for me to fill in, and annotated into the display afterwards. It seems like an unnecessary step to reify it and force the bytes to be present in the the saved file.
> Given C++, I can't help but hold things wrong and shoot myself
Give an example. I have been programming in C/C++ for close to 30 years and the places where I worked had very strict guidelines on C++ usage. We could count the number of times we shot ourselves due to the language.
The numeric conversion functions in the STL are terrible. They will happily accept strings with non-numeric characters in them: they will convert "123abc" to 123 without giving an error. The std::sto* functions will also ignore leading whitespace.
Yes, you can ask the std::sto* functions for the position where they stopped because of invalid characters and see if that position is the end of the string, but that is much more complex than should be needed for something like that.
These functions don't convert a string to a number, they try to extract a number from a string. I would argue that most of the time, that's not what you want. Or at least, most of the time it's not what I need.
atoi has the same problem of course, but even worse.
Forcing people to explicitly casts everything all the time means that dangerous casts don't stand out as much. That's an L for rust imo.
Editorial Channel
What the content says
ND
PreamblePreamble
Content does not address human dignity, equal rights, or foundational human rights principles
ND
Article 1Freedom, Equality, Brotherhood
Content does not discuss equal and inalienable rights
ND
Article 2Non-Discrimination
Content does not address discrimination or equality
ND
Article 3Life, Liberty, Security
Content does not discuss right to life, liberty, or personal security
ND
Article 4No Slavery
Content does not address slavery or servitude
ND
Article 5No Torture
Content does not discuss torture or cruel/degrading treatment
ND
Article 6Legal Personhood
Content does not address recognition as person before law
ND
Article 7Equality Before Law
Content does not discuss equal protection before law
ND
Article 8Right to Remedy
Content does not address right to remedy for violations
ND
Article 9No Arbitrary Detention
Content does not discuss arbitrary arrest or detention
ND
Article 10Fair Hearing
Content does not address right to fair and public trial
ND
Article 11Presumption of Innocence
Content does not discuss presumption of innocence
ND
Article 12Privacy
Content does not address privacy, family, home, or correspondence
ND
Article 13Freedom of Movement
Content does not address freedom of movement
ND
Article 14Asylum
Content does not discuss right to asylum
ND
Article 15Nationality
Content does not address nationality or right to change nationality
ND
Article 16Marriage & Family
Content does not discuss marriage or family rights
ND
Article 17Property
Content does not address property ownership rights
ND
Article 18Freedom of Thought
Content does not discuss freedom of conscience, thought, or religion
ND
Article 19Freedom of Expression
Medium Practice
Content does not advocate for freedom of expression but exercises and demonstrates it
Observable Facts
The blog post allows and displays reader comments with multiple technical perspectives.
Comments include technical criticism of the article's arguments and alternative language suggestions (C++20 concepts, C#, Swift comparisons).
The author and commenters freely express opinions and recommendations without apparent editorial censorship.
Inferences
The platform's publication of dissenting commentary suggests structural support for diverse viewpoints and free expression.
The lack of comment moderation visible in the thread indicates openness to critical feedback.
ND
Article 20Assembly & Association
Content does not address freedom of assembly or association
ND
Article 21Political Participation
Content does not discuss political participation or voting
ND
Article 22Social Security
Content does not address social security or economic rights
ND
Article 23Work & Equal Pay
Content does not discuss right to work or labor standards
ND
Article 24Rest & Leisure
Content does not address rest, leisure, or reasonable working hours
ND
Article 25Standard of Living
Content does not discuss standard of living, health, or social services
ND
Article 26Education
Content does not advocate for right to education, though it serves educational function
ND
Article 27Cultural Participation
Content does not address participation in cultural or scientific life
ND
Article 28Social & International Order
Content does not discuss social and international order
ND
Article 29Duties to Community
Content does not address duties to community
ND
Article 30No Destruction of Rights
Content does not discuss prevention of rights destruction
Structural Channel
What the site does
+0.20
Article 19Freedom of Expression
Medium Practice
Structural
+0.20
Context Modifier
+0.20
SETL
ND
Blog platform enables and publishes free expression through author commentary and diverse reader comments; dissenting technical opinions are allowed and visible
ND
PreamblePreamble
No structural signals relevant to preamble themes
ND
Article 1Freedom, Equality, Brotherhood
No structural signals regarding equality of rights
ND
Article 2Non-Discrimination
No structural signals regarding non-discrimination
ND
Article 3Life, Liberty, Security
No structural signals regarding personal safety
ND
Article 4No Slavery
No structural signals regarding freedom from slavery
ND
Article 5No Torture
No structural signals regarding torture prevention
ND
Article 6Legal Personhood
No structural signals regarding legal personhood
ND
Article 7Equality Before Law
No structural signals regarding legal equality
ND
Article 8Right to Remedy
No structural signals regarding legal remedies
ND
Article 9No Arbitrary Detention
No structural signals regarding detention rights
ND
Article 10Fair Hearing
No structural signals regarding judicial fairness
ND
Article 11Presumption of Innocence
No structural signals regarding criminal procedure
ND
Article 12Privacy
Matomo analytics tracking present on page without explicit privacy safeguards observed
ND
Article 13Freedom of Movement
No structural signals regarding movement rights
ND
Article 14Asylum
No structural signals regarding asylum or refuge
ND
Article 15Nationality
No structural signals regarding nationality rights
ND
Article 16Marriage & Family
No structural signals regarding family law
ND
Article 17Property
No structural signals regarding property
ND
Article 18Freedom of Thought
No structural signals regarding conscience or belief
ND
Article 20Assembly & Association
No structural signals regarding assembly or association rights
ND
Article 21Political Participation
No structural signals regarding political participation
ND
Article 22Social Security
No structural signals regarding social protection
ND
Article 23Work & Equal Pay
No structural signals regarding work or employment rights
ND
Article 24Rest & Leisure
No structural signals regarding leisure or rest
ND
Article 25Standard of Living
No structural signals regarding living standards
ND
Article 26Education
Blog post provides technical knowledge and learning resources freely and without access barriers
ND
Article 27Cultural Participation
No structural signals regarding cultural participation
ND
Article 28Social & International Order
No structural signals regarding international order
ND
Article 29Duties to Community
No structural signals regarding community duties
ND
Article 30No Destruction of Rights
No structural signals regarding rights protection
Supplementary Signals
Epistemic Quality
0.77
Propaganda Flags
1techniques detected
appeal to authority
Article opens by establishing credibility through Matt Godbolt's reputation: 'Matt Godbolt, of Compiler Explorer fame, is awesome and you should scour the web for every single bit of content he puts out.'
Solution Orientation
No data
Emotional Tone
No data
Stakeholder Voice
No data
Temporal Framing
No data
Geographic Scope
No data
Complexity
No data
Transparency
No data
Event Timeline
20 events
2026-02-26 21:34
eval_success
Evaluated: Neutral (0.34)
--
2026-02-26 20:01
dlq
Dead-lettered after 1 attempts: Matt Godbolt sold me on Rust by showing me C++
--
2026-02-26 20:00
dlq
Dead-lettered after 1 attempts: Matt Godbolt sold me on Rust by showing me C++
--
2026-02-26 20:00
eval_failure
Evaluation failed: Error: Unknown model in registry: llama-4-scout-wai
--
2026-02-26 20:00
eval_failure
Evaluation failed: Error: Unknown model in registry: llama-4-scout-wai
--
2026-02-26 19:59
rate_limit
OpenRouter rate limited (429) model=llama-3.3-70b
--
2026-02-26 19:58
rate_limit
OpenRouter rate limited (429) model=llama-3.3-70b
--
2026-02-26 19:57
rate_limit
OpenRouter rate limited (429) model=llama-3.3-70b
--
2026-02-26 19:55
rater_validation_fail
Validation failed for model llama-4-scout-wai
--
2026-02-26 19:11
dlq
Dead-lettered after 1 attempts: Matt Godbolt sold me on Rust by showing me C++
--
2026-02-26 19:10
rate_limit
OpenRouter rate limited (429) model=llama-3.3-70b
--
2026-02-26 19:08
rate_limit
OpenRouter rate limited (429) model=llama-3.3-70b
--
2026-02-26 19:07
rate_limit
OpenRouter rate limited (429) model=llama-3.3-70b
--
2026-02-26 06:53
dlq
Dead-lettered after 1 attempts: Matt Godbolt sold me on Rust by showing me C++
--
2026-02-26 06:52
dlq
Dead-lettered after 1 attempts: Matt Godbolt sold me on Rust by showing me C++
--
2026-02-26 06:51
dlq
Dead-lettered after 1 attempts: Matt Godbolt sold me on Rust by showing me C++
--
2026-02-26 06:49
dlq
Dead-lettered after 1 attempts: Matt Godbolt sold me on Rust by showing me C++
--
2026-02-26 06:48
dlq
Dead-lettered after 1 attempts: Matt Godbolt sold me on Rust by showing me C++
--
2026-02-26 06:45
dlq
Dead-lettered after 1 attempts: Matt Godbolt sold me on Rust by showing me C++