I also find if you write modern, idiomatic C++ code you rarely, if ever, have to worry about memory safety issues.
I also find if you write modern, idiomatic C++ code you rarely, if ever, have to worry about memory safety issues.
This is empirically not true. Tons of memory safety issues are found (and exploited) all the time in modern idiomatic C++ codebases.
For example my latest game server is up more than 2 month already and the only reason it gets restarted is that I am updating it with the new version.
https://twitter.com/lazyfishbarrel is very much worth reading.
For years, we've been telling newbies not to use the expression "C/C++", which is incorrect. Now the Rust community disingenuously keeps pushing this outdated meme; I say it's disingenuous because they are informed enough to know that C and C++ are distinct languages, yet they use the well-known flaws of C to attack C++ when it can advance their moral crusade for memory safety.
These issues are every bit as much of problems in C++. In fact, there is a reasonable argument that modern C++ is less safe than old C++, because of features like lambdas that practically invite use-after-free.
It reports a total of 37 issues in:
- freetype2 (C lib, 20+ years old)
- usrsctp (C lib, age unknown)
- libexif (C lib, age unknown)
- libxslt (C lib, 20+ years old)
- imagemagick (C lib, 20+ years old)
- mruby (C)
- php (C)
- openSSL (C, 20+ years old)
- curl (C lib, 20+ years old)
- ffmpeg (C lib, 18 years old)
- ghostscript (C lib, 30 years old)
- irssi (C, 20 years old)
In that list were also Skia and libsass, two projects actually written in C++.In Sass, the issue is a nullptr issue: https://github.com/sass/libsass/issues/3001
In Skia the bug was in intrinsics code: https://skia.googlesource.com/skia/+/0f55db539032a23b52897ae...
Of course that's a single data point, but it shows what I think is a reasonable argument: most of the issues indeed happen in (old) C code, for well-known reasons (no standard string, array or collection support, no RAII), but because C++ supports those things by default it largely avoids those issues.
But that's not really an issue in modern C++. It's only really a problem when you want to implement your own data structures with raw pointers, in which case, yes, you have to be careful and write tests and use sanitizers, Valgrind, etc.
In my own cases I use proprietary protocols for client-server communications that more or less ensure that memory bounds are not broken.
Of course attackers might be able to punch holes in lower layers ( UDP for example ) over which I have no direct control but in this case Rust would use the same UDP stack and offer no advantage.
> This is empirically not true. Tons of memory safety issues are found (and exploited) all the time in modern idiomatic C++ codebases.
I smell sarcasm here. I do not claim my code to be unbreakable. I do believe it is REASONABLY safe by design. pcwalton's claim is generic claim about generic code that may have no relevance to particular situations. Mine for example
- raw mallocs : https://github.com/mozilla/gecko/blob/central/dom/plugins/ip...
- new / delete : https://github.com/mozilla/gecko/blob/central/dom/plugins/ip...
- "whatever.Allocate<T>" : https://github.com/mozilla/gecko/blob/central/dom/plugins/ip...
and that's not limited to a single file... look at this :
https://github.com/mozilla/gecko/blob/3e6d6e013400af38f85ceb... - some malloc and new, again
- you also get some unique_ptr (because "modern" m'see) : https://github.com/mozilla/gecko/blob/3e6d6e013400af38f85ceb...
- moz_xmalloc because why not ? https://github.com/mozilla/gecko/blob/3e6d6e013400af38f85ceb...
- oh and did you know about our own custom reference counting pointer ? https://github.com/mozilla/gecko/blob/3e6d6e013400af38f85ceb...
etc etc... when you've got 35 different ways to allocate objects used willy-nilly of course things go wrong. Most modern codebases only ever use automatic storage, and unique / shared_ptr.
Mozilla could have achieved 90% of what it wanted from a rust rewrite with a modern C++11 rewrite at a quarter of the cost. Linter rules that say "no new or delete", "either unique_ptr<T> or shared_ptr<const T>", and "only construct unique or shared ptr via make_unique and make_shared" get them like three quarters of the way there.
The thing that makes rust great is that the static analyzer is built into the compiler and has strict defaults. C++ is the same language, but clang-analyze and clang-tidy are shipped as separate packages and have more permissive defaults.
There is a reasonable argument that modern C++ is less safe than old C++, because features like lambdas are very prone to use-after-free.
Thats the whole point. You need to do these things in C++, not in rust. In rust you get it for free and dont need to be an expert and use runtime detection tools or even static analyzers besides your compiler (w.r.t to memory safety and some classes of data races. These things can be useful in other domains)
People make the same assertions about dynamically typed languages at scale and how you "only" need to write tests that assert the types or "i wrote the function and know which type is passed duh" or "i write unit tests that would catch this" when a statically typed language tells you at compile time whether or not it will work. No intelligence required.
Hopefully you're not only relying on those - valgrind, address sanitizer, fuzzing tools, static analysis, etc. are a must for network-facing C++ (or unsafe Rust) as far as I'm concerned. You're not just looking for leaks, but use after free bugs, single byte overflows, bad casts triggered by bad data, and a whole slew of other potential problems.
I don't understand the desperate need to paint all modern C++ code bases as dangerously unsafe. It is demonstrably not true and doesn't reflect well on the motivations of those that would blindly assert it. Modern C++ has many issues and, like all programming languages, is the scene of many bugs. Just not memory safety issues. Furiously asserting that memory safety is an issue does not manufacture fact.
Because the idea that security vulnerabilities can be fixed by just "modernizing" C++ codebases is actively harming security, by discouraging investment in memory-safe languages.
> It is demonstrably not true and doesn't reflect well on the motivations of those that would blindly assert it.
It is demonstrably true, as http://twitter.com/lazyfishbarrel shows. Perhaps consider that those of us who work on browsers, which are some of the largest most-attacked pieces of software in the world, would know what we are talking about.