Rust dev cites unsafe stats while C++ cat enjoys oblivious dinner smugly
Why is this Languages meme funny?
Level 1: No Rules, No Problem
Imagine two friends talking about riding bikes. One friend says, “I almost never ride without a helmet. In fact, only about 19% of my rides have ever been without wearing my helmet.” They’re proud because wearing a helmet is a safety rule, and they rarely break that rule. Now the other friend laughs smugly and says, “Well, I never wear a helmet on my rides – not even once!” At first, that sounds like the second friend is even more impressive or daring. But then you realize the second friend’s bike didn’t come with a helmet at all, and they never even thought about wearing one. They aren’t safer; they just never had that safety rule to begin with. The first friend is all about safety gear, and almost always uses it. The second friend acts proud about a zero in their stats, but the zero only exists because they ignore safety entirely. 😼🚲
In this meme, Rust is like the first friend – it has safety measures (rules/helmet) and very rarely needs to ignore them. C++ is like the second friend – it doesn’t have an automatic safety measure (no helmet provided), so it claims “zero uses of safety override” as if that’s a good thing. The joke is that saying “I’ve never broken the safety rules” doesn’t mean much when you have no safety rules. The annoyed person on the left is yelling about how safe Rust is, and the cat on the right is basically bragging in a clueless way, which is why it’s funny. Even someone without technical knowledge can giggle at the dynamic: one side cares a lot about following safety guidelines, and the other side goes, “Hah, I don’t even have guidelines and I’m fine!” – completely missing the point. It’s that silly disconnect that makes the meme work, showing how different the two “friends” (or in this case, programming languages) really are when it comes to playing safe.
Level 2: Explicit Unsafe vs Implicit Danger
Let’s break down the joke in simpler terms. We have two programming languages, Rust and C++, which are often compared because both are used for systems and other low-level programming tasks where performance is critical. However, they have very different approaches to safety. Rust has a special language feature – the unsafe keyword – which a programmer uses when they need to do something that the Rust compiler can’t guarantee is safe. In contrast, C++ doesn’t have such a keyword at all. That difference is exactly what this meme is playing with.
In Rust, by default, the compiler is like a strict safety inspector. It enforces a lot of rules to ensure memory safety and type safety. For example, Rust won’t let you:
- Use a pointer or reference after the data it points to has been freed (avoiding dangling pointers and use-after-free errors).
- Modify data from two different places at the same time in an uncontrolled way (avoiding data races in concurrent code).
- Read beyond the end of an array or buffer (avoiding buffer overruns).
If you try to do something that violates these rules, Rust will usually refuse to compile your code, or it will enforce a runtime check (like array bounds checking) that stops the program with an error rather than let it proceed incorrectly. This means that safe Rust code – code that doesn’t use the unsafe escape hatch – is guaranteed (by the language) not to exhibit certain kinds of bugs that often plague C++ programs. This is a big deal in terms of software CodeQuality and reliability. It drastically reduces the chances of things like segmentation faults (crashes) or mysterious memory corruption.
However, sometimes a systems programmer needs to do something inherently low-level, like directly manipulate memory or call a function from C or do some bit-twiddling optimizations. Rust acknowledges that need with the unsafe keyword. When you wrap a section of code in an unsafe { ... } block, you’re basically telling the compiler: “I know what I’m doing – allow me to bend the rules here.” Inside an unsafe block, Rust will let you do things like dereference raw pointers or call foreign functions, which it normally would be very strict about. The catch is, when you do that, you the programmer are responsible for upholding safety – the compiler steps back and trusts you not to introduce a bug. It’s a bit like disabling the guardrails temporarily. The idea is that you use unsafe only when you must, and even then, you try to encapsulate it and still ensure overall correctness. A well-known saying in the Rust community is, “you should encapsulate unsafe code in safe abstractions,” meaning you do the dirty work in one place and present a clean, safe interface to the rest of the program.
Now, the meme cites “Only 19.11% of all Rust libraries use unsafe keyword.” This suggests that in about 80% of Rust libraries (crates), the developers never needed to write any unsafe code at all – everything could be done within Rust’s safe guarantees. That statistic highlights how far Rust’s safety net extends: most of the time, you don’t need to turn off the checks. Rust provides safe APIs for a lot of functionality (networking, threading, data structures, etc.), so you rarely have to get your hands dirty with raw pointers. Rustaceans view that as a very positive thing: it means the ecosystem largely runs on guaranteed-safe code, with only a small portion that had to go “close to the metal” and use unsafe. It’s like saying, “Out of all the building projects, only 19% ever had to remove the safety harness.” It implies confidence in Rust’s safety-first design.
C++, on the other hand, comes from a different school of thought. C++ gives you raw power by default. There are no automatic runtime checks for memory safety unless you explicitly use tools or smart pointers or libraries that do so. There isn’t a built-in concept of “this is safe” vs “this is unsafe” code in the language – the programmer is expected to know and handle the risks. If you want to dereference a pointer in C++, you just do it; if that pointer was invalid, your program is in trouble (it might crash or worse). If you want to index an array beyond its bounds, C++ will let you try – it won’t stop you or even warn you (unless you’re in a debugging mode or use special library containers). Doing these things in C++ leads to what we call undefined behavior – basically, the outcome is not predictable or defined by the language. The program might crash, or it might continue with garbage data, or it might seemingly work fine but corrupt something that causes an issue later. Undefined behavior is one of the scariest things in C++ because it means a simple mistake can potentially compromise the whole program’s correctness and security, and the language won’t tell you at the point of error.
So when the right side of the meme says “None of the C++ libraries use the unsafe keyword,” it’s playing on that literal truth. It sounds like a triumphant statement – wow, zero libraries had to use unsafe, amazing! – but the reason is simply that C++ doesn’t have an unsafe keyword at all. C++ code can directly perform what Rust would call unsafe operations without any special marker or permission. In a sense, all C++ code is potentially “unsafe code” because the language doesn’t enforce safety. The meme is making a witty comparison: Rust counts and limits its “dangerous code” (unsafe blocks are counted and clearly only a minority), whereas C++ just has dangerous code everywhere by default but doesn’t label it. It’s like comparing apples to oranges in a facetious way: Rust’s apple comes with a “poisonous core” warning label when applicable, C++’s orange just never labels any part as poisonous even if it might be.
To a junior developer or someone new to these languages, it might help to see a quick example of what we’re talking about:
// Rust example: accessing an array safely vs using unsafe.
fn main() {
let nums = [1, 2, 3];
println!("Safe access: {}", nums[2]); // prints 3, index 2 is in bounds.
// println!("{}", nums[5]);
// ^-- This line, if uncommented, would cause a panic at runtime
// because it's an out-of-bounds access. Rust detects this and stops the program safely.
// Now, using an unsafe block to do something low-level:
let p: *const i32 = nums.as_ptr(); // raw pointer to the first element of the array
unsafe {
// We dereference the raw pointer inside an unsafe block.
// We promise that this is a valid pointer (which it is, pointing to nums[0]).
println!("First element via raw pointer: {}", *p);
}
// If we had messed up and p was invalid, the above unsafe code could crash or corrupt data.
}
// C++ example: accessing an array (no automatic safety checks).
#include <iostream>
int main() {
int nums[3] = {1, 2, 3};
std::cout << "Safe access: " << nums[2] << std::endl; // prints 3, index 2 is in bounds.
// The following line will compile and run without any warning,
// but it is an out-of-bounds access and causes undefined behavior:
std::cout << "Out of bounds access: " << nums[5] << std::endl;
// Using a raw pointer in C++ (no special keyword needed):
int *p = nums; // raw pointer to the first element
std::cout << "First element via raw pointer: " << *p << std::endl; // prints 1 (nums[0])
p = nullptr;
// std::cout << *p;
// ^-- This would compile fine, but dereferencing a nullptr is undefined behavior (likely crash).
}
In the Rust code above, trying to access nums[5] (which is outside the array) results in a runtime panic – essentially Rust stops the program with an error message rather than let you proceed with something bogus. In the C++ code, nums[5] is undefined behavior: the program might print some garbage value or crash immediately. Rust made us wrap the raw pointer dereference in an unsafe block to signal “here be dragons,” whereas C++ let us do *p (and even *p when p was null, if we uncommented that) without a peep. In Rust, you literally cannot dereference a raw pointer without marking it unsafe – it’s the language forcing you to acknowledge “I’m doing something risky here.” In C++, there’s no such acknowledgement; the language sorta shrugs and says “good luck.”
Now, coming back to the meme text: the Rust side says only 19.11% of Rust libraries use unsafe. That implies roughly one in five Rust libraries ever needed to do something the compiler couldn’t check. The C++ side says none of the C++ libraries use unsafe, which on the surface sounds even better… except it’s only because C++ doesn’t check or record that info at all. It’s a bit like someone bragging they have a perfect safety record because they never do inspections. If a junior developer knows at least that Rust is known for safety and C++ is more old-school, they’ll see the joke: it’s a sarcastic comparison. The cat is effectively saying, “Ha, we have 0% unsafe usage,” which is a nonsense metric for C++.
This meme uses the well-known “woman yelling at cat” template: usually one side is very upset and the other side (the cat) is nonchalant and missing the point. Here the “upset woman” is the Rust community or advocate, shouting a fact about a Rust language feature (the unsafe keyword usage). The “smug cat” is the C++ side, replying with a literal but context-ignoring statement. The humor comes from that mismatch in perspective. Everyone at the table (the audience in this case) can see that the cat’s reply is kind of silly — it deliberately overlooks why the Rust person is citing the statistic. But that’s what makes it a joke. It’s poking fun at C++ by using C++’s own lack of a safety mechanism as if it were a bragging right. For someone learning programming, the takeaway is: Rust is explicit about unsafe code (and prides itself on being safe by default), while C++ doesn’t even have the notion of “unsafe code” inside the language, so it can’t boast about being safe — it can only pretend by this kind of cheeky logic.
Level 3: Memory Safety Food Fight
On a more practical level, this meme captures the endless Rust vs C++ debate that many veteran developers know all too well. The two-panel “woman yelling at cat” meme template is a perfect staging for this argument. On the left, you have the Rust developer (the yelling woman) furiously pointing and citing a statistic: “Only 19.11% of all Rust libraries use the unsafe keyword!” You can almost hear the passion: Rustaceans (Rust fans) love to emphasize how safe Rust is – that memory errors are mostly a thing of the past because the compiler is so strict. That 19.11% figure sounds like evidence in a heated argument about code quality: “See? The vast majority of our code doesn’t ever need to break the rules. Rust lets you write system-level code with guarantees!”
On the right, we have the classic smug white cat (representing a C++ old-timer or the collective persona of C++ code) sitting in front of a salad, looking indifferent and superior. The cat’s retort: “None of the C++ libraries use the unsafe keyword.” Delivered with that petty, oblivious smugness, it’s a punchline that makes experienced programmers chuckle. Why? Because it’s a facetious, almost trollish response that entirely misses the point on purpose. It’s technically true – in C++ you will never find an unsafe keyword in any library – but not for the reason that implies safety! It’s true by trivial default: C++ doesn’t require you to mark dangerous operations as dangerous. The cat is basically saying, “Ha! 0% > 19%, checkmate,” while completely ignoring the context that makes those numbers meaningful. This is classic system programming snark: using a literal truth to poke fun at an argument in a sarcastic way.
To a seasoned developer, the humor here draws on shared experiences and the culture clash between these two languages. Rust is the new kid on the block in low-level systems programming, emphasizing memory safety, strict type safety, and zero-cost abstractions that prevent whole classes of bugs. It has slogans like “fearless concurrency” and a very vocal community that often touts how Rust avoids the pitfalls that plague C and C++ (like null pointer dereferences, buffer overflows, data races, you name it). On the other hand, C++ is a venerable workhorse language – powerful, fast, but with that power comes responsibility. Long-time C++ developers have been living without a safety net for decades, relying on experience, testing, and tools like sanitizers to catch mistakes. There’s a bit of a pride in that culture of “we manage just fine without the training wheels.” The cat’s smug look captures that attitude perfectly: it’s the face of a C++ veteran who is either oblivious to the Rust dev’s point or deliberately pretending not to care.
The meme nails an archetypal exchange:
- Rust dev: “Our language is so safe, we almost never need to go outside the safety rules – see, only ~19% of libraries ever use
unsafe!” - C++ dev (smirking): “Oh yeah? Well in C++ zero libraries use
unsafebecause we don’t even have those silly rules, so there!”
It’s the “you’re bragging about something we dismiss” kind of comeback. Experienced engineers find this funny because it reflects real discussions (and flame wars) they’ve seen. It highlights a truth about language comparison: Rust and C++ have fundamentally different philosophies. Rust’s explicit unsafe is essentially a built-in admission that “sometimes we must do dangerous things, but we label them and contain them.” C++’s approach is “the whole world is dangerous, we assume you, the programmer, know what you’re doing.” When the cat says “None of the C++ libraries use the unsafe keyword,” it’s willfully ignoring that in C++ you cannot distinguish safe code from unsafe code – it’s all one bucket. That absurd inversion – turning the lack of safety checks into a boast – is what elicits a knowing laugh. It’s the same energy as someone proudly claiming they have zero accidents on record simply because they don’t record accidents.
On a deeper level, the meme is also hinting at the progress of software engineering. C++ was created in the 1980s, when the norms of low-level programming were that you deal with memory yourself and accept the risks. Rust emerged in the 2010s with the wisdom that many security vulnerabilities and bugs (in browsers, operating systems, etc.) stem from memory unsafety. Rust tried to solve that by design – adding compile-time checks to prevent those errors. The result is a language where you feel the compiler’s strictness (sometimes Rust’s borrow checker can be frustrating), but it’s generally for your own good. The Rust dev in the meme brandishing the 19.11% statistic is effectively saying, “Look how well our strict approach works – we almost never have to turn off the seatbelt.” The C++ cat’s quip is a reminder of the old guard’s mindset: “Seatbelts? We didn’t bother with those – we ride or die free.” It’s an eye-roll inducing response that Rust proponents would recognize as evasive, but it’s definitely something you’d hear from a cheeky C++ fan or a meme in a C++ forum.
The contrast in the meme also touches on code quality and developer experience. Rust, by enforcing safe code, arguably leads to more robust libraries out-of-the-box; C++ puts the onus on the developer’s discipline. Seasoned devs have war stories: a missed null check causing a crash, a buffer overflow causing a security hole – all in C/C++ code. Rust was explicitly designed to eliminate those particular nightmares (the kind that wake you up at 3 AM with a Segmentation Fault in production). So the yelling woman’s anger might also resonate as, “How can you be smug about not having safety? Don’t you care about all those crashes and bugs!?” And the cat’s face basically says, “Not really bothered; I’ve accepted that world.” This interplay encapsulates a lot of the emotional charge behind Rust vs C++ discussions. The punchline works because both sides in the meme speak past each other: one cites a meaningful safety stat, the other responds with a meaningless rhetorical gotcha. It’s absurd and yet perfectly mirrors a certain brand of internet argument.
In summary, for those in the know, this meme is a playful jab at C++’s lack of built-in safety and Rust’s proud emphasis on it. It’s a “memory safety food fight” at the dinner table: Rust’s side flinging facts and C++’s side flinging back a dismissive one-liner. Both the Languages are being personified – one is conscientious and a stickler for rules, the other is jaded and cavalier. That dynamic is instantly recognizable to developers, which is why this image macro can spark laughter (and probably another round of language banter in the comments).
Level 4: Soundness vs Undefined Behavior
At the most theoretical level, this meme highlights a clash between language soundness and undefined behavior in system programming. Rust is designed around a sound type system that guarantees memory safety by construction for all code not explicitly marked as unsafe. This means that in safe Rust, the compiler’s borrow checker and ownership rules enforce strict guarantees: no use-after-free, no data races, no dangling pointers, no buffer overflows. In formal terms, Rust uses concepts from advanced type theory (like affine types and lifetimes) to ensure that certain classes of errors are provably impossible in safe code. The moment you write an ordinary Rust function without any unsafe blocks, you can trust that the compiler has rigorously checked it for memory safety violations. It’s as if Rust provides a lightweight form of formal verification for everyday programming: illegal memory accesses are caught at compile time (or turned into runtime aborts like panics on out-of-bounds), essentially making illegal states unrepresentable unless you explicitly opt out.
The unsafe keyword in Rust is an explicit opt-out from this safety regime. Inside an unsafe { ... } block, the compiler relaxes some of its strict rules – you can dereference raw pointers, call foreign C functions, or perform other low-level operations that the compiler cannot guarantee are safe. However, Rust’s philosophy is that you should encapsulate and minimize such code. The statistic “Only 19.11% of all Rust libraries use the unsafe keyword” reflects that philosophy: in about 80% of Rust crates, developers never needed to leave the safe world at all. That’s a remarkable figure from a language design perspective – it indicates that Rust’s abstractions (iterators, smart pointers, concurrency primitives, etc.) cover most use-cases without requiring a dip into unsafe territory. In other words, the Rust ecosystem achieves most tasks with enforced memory safety, resorting to unsafe code in only a fifth of libraries. This isn’t just a bragging point; it’s evidence of Rust’s success in balancing low-level programming capability with type safety and memory safety guarantees.
Now consider C++. C++ comes from a lineage (C and assembly) where performance and control are paramount, and the language places trust in the programmer for safety. There is no unsafe keyword in C++ because, by default, the language allows you to do things that Rust would consider unsafe at any time. You can cast any pointer to any type, perform pointer arithmetic, access memory out of bounds, or deallocate memory and keep using the pointer – and the compiler won’t stop you. The result is that C++ has numerous footguns: powerful features that, if misused, can lead to serious errors. The C++ standard simply calls these scenarios undefined behavior (UB), meaning the language makes no guarantees about what happens – the program might crash immediately, or it might subtly corrupt data and keep running. Compilers will even assume certain bugs “can’t happen” and optimize accordingly (for example, if you invoke UB, the compiler might optimize away what it thinks are unnecessary checks, potentially making the program do bizarre things). From a theoretical standpoint, C++ trades safety for flexibility: it’s unsound in the sense that well-typed, compiled C++ code can still have memory errors. Ensuring memory safety in C++ in general is as hard as solving the halting problem – essentially unprovable without severely restricting what the code can do.
So what does “None of the C++ libraries use the unsafe keyword” really mean? It’s a tongue-in-cheek statement pointing out a vacuous truth. Because C++ has no built-in notion of safe vs. unsafe code, it follows that 0% of C++ libraries use an unsafe marker. The cat in the meme is smugly implying “C++ must be super safe, since you never see us marking anything unsafe!” – but of course, the real reason is that everything in C++ can potentially be unsafe, just without any explicit label. It’s like saying “Our code has zero known restrictions” and passing it off as a virtue. Seasoned language theorists and experienced programmers recognize this as a fundamental design difference: Rust has a closed, well-defined safe subset with an escape hatch (unsafe) for the rare cases, whereas C++ operates in an open world where the programmer is responsible for all safety, and the language runtime does not intervene. The humor is rooted in this deep context – it’s poking fun at how a memory-safe language measures and prides itself on a low usage of its escape hatch, while an unsafe language pretends to gloat about not needing an escape hatch that it never had. It’s a bit of logical wordplay that underscores decades of evolution in programming language design.
Description
Side-by-side meme using the classic “woman yelling at cat” template. Left panel: two women from a reality-TV scene (faces blurred) with one leaning forward, arm outstretched, angrily pointing; caption above reads “Only 19.11% of all rust libraries use unsafe keyword”. Right panel: the famous white cat sitting at a dinner table (face blurred) looking unimpressed in front of a half-eaten salad; caption above reads “None of the c++ libraries use the unsafe keyword”. The humor contrasts Rust’s explicit ‘unsafe’ escape hatch with C++’s implicit freedom to cause undefined behavior, highlighting veteran debates on memory safety, type systems, and low-level programming responsibility
Comments
13Comment deleted
C++ doesn’t need an ‘unsafe’ keyword - the standard silently assumes you already signed the segmentation-fault waiver
The real unsafe keyword in C++ is 'int main()' - it's where the undefined behavior warranty begins and your debugger's therapy sessions start
The real joke is that C++ developers have been writing 'unsafe' code for decades without needing a keyword to mark it - when everything is unsafe by default, nothing is. Meanwhile, Rust developers meticulously track that 19.11% like it's a code coverage metric, because in Rust, explicitly opting out of safety guarantees is the exception that proves the rule. It's the difference between a language that assumes you know what you're doing with raw pointers and one that makes you pinky-swear you understand the consequences before letting you segfault
Rust fences off unsoundness behind a keyword; C++ treats it like a codegen hint and sells you ASan/UBSan as PPE
Rust: 19.11% of crates label the escape hatches; C++: the whole airframe is an escape hatch, it’s just called undefined behavior
Rust: unsafe is opt-in. C++: safe is opt-out... good luck with that UB lottery
Only 19.11% of the c++ libraries use safe keyword Comment deleted
I doubt, that the number is that high 😄 Comment deleted
So they are really proud that every 5th library ignores borrow checker?😂 Comment deleted
I'd be interesting to have statistics of what unsafe is used for… Anyways it's a bit more complex that that, at the very least it's "using features that may allow bypassing the borrow checker" Comment deleted
I'd this somehow isn't bait: This isn't about irgnoring borrow checker but if you work with a FFI and/or OS shenanigans you often need unsafe Comment deleted
me when i don't know what i'm talking about Comment deleted
I would rather have unsafe in libs than RefCells and shit like that, fastest solutions aren't always in the "borrow checker pleasing" subset of programs. (I could use RefCell for each cell in a grid for a water simulation, but that introduces runtime costs, so I had to use get_many_mut_unchecked + similar methods and unsafe) Comment deleted