I disagree with the blanket statement “C++ isn’t memory safe”. C++ provides the tools for writing memory-safe code, but it does not enforce it by default.
This is such a weird take. C++ isn’t memory safe. The blanket statement is… true. You say as much in the second sentence.
With C++, you retain full control over memory management and can choose the best tool for the job. You’re not boxed into a strict ownership model that may force refactoring or add extra layers of abstraction.
You have full control in Rust too, at least to the same extent as C++. Rust isn’t memory safe either. Rust is just the opposite of C++ in the approach to safety: you opt in to being unsafe with the unsafe
construct instead of being unsafe by default. They’re just different paradigms. I’d actually argue that you don’t have full control in either language unless you opt in to it, modern C++ tries very hard to abstract away memory management. You can write an entire program without a single new
or malloc
, which is pretty great.
Sure, mistakes can happen, but with proper practices and modern C++ features you can achieve a level of safety that meets most needs without sacrificing the expressiveness and efficiency you might require in complex systems.
This is just simply not true and is consistently proven incorrect every time an aspect of C++'s memory unsafety is exploited. I work in security and I still, in 2025, exploit memory corruption. The best developers money can buy still make mistakes with C and C++.
Besides that: which conventions do you mean?
The way you have to interact with smart pointers for example:
#include <memory>
int main(int argc, char** argv)
{
std::unique_ptr<int> a = std::make_unique<int>(1);
std::unique_ptr<int> b(a.get());
}
Double free, but compiles without warning. It’s convention to not use unique_pointer
’s constructor, not enforced.
#include <iostream>
#include <string>
int main(int argc, char** argv)
{
const char* c;
{
std::string a("HelloThisIsAHeapString");
c = a.c_str();
}
std::cout << c << std::endl;
}
Use after free. No compiler error or warning, it’s convention to not maintain references to C++ string data, not enforced.
That’s all fine, whatever, but these are conventions. We’ve shot ourselves in the foot a million times and come up with our own guard rails, but the developer needs to know all of them to not make the mistake.
The definition of “a memory safe programming language” is not in debate at all in the programming community. I have no idea why you’re trying to change it.
This is incredibly arrogant, and, tbh, ignorant.
You missed the point of the examples: those aren’t necessarily “easy mistakes” to make and of course a UAF is easy to spot in a 4 line program, the point is that there is no language construct in place to protect from these trivial memory safety issues. With respect to the “obviousness” of the
std::string
mistake, if you instead consider an opaque interface that requires aconst char*
as an input, you have no idea if it is going to try to reference of that pointer or not past the lifetime of thestd::string
. If you can’t see past the simplicity of an example to the bigger picture that’s not on me.