← Back to context

Comment by pcwalton

1 year ago

I've been seeing C++ fans talk about how they never see memory safety issues in practice in C++ for a decade and a half. I even believed it sometimes. But if there's ever been a common story over those 15 years, it's that these anecdotes mean little, and the actual memory safety property means a lot.

The only time I've seen "almost memory safe" actually work is in Go and Swift, which have memory safety problems with concurrency, but they're actually rare enough not to matter too much (though in Go's case it would have been easy to design interfaces and slices not to have the problem, and I wish they had). I simply don't believe that Zig is meaningfully more memory safe than C++.

I don't see any Zig repositories under https://github.com/pcwalton

Is your opinion based on anything other than pure speculation?

I think it makes more sense to form an opinion after actually having tried Rust, C++, and Zig in earnest.

There are lots of us out there who've done it. Join us!

I think it's possible to retrofit race-safe slices and interfaces into Go, and I expect it to happen one day once some actually relevant code execution exploit shows up.

There's going to be some impact and low-level libraries that manipulate directly the words that constitute slices and interfaces, and there will some slight performance impact and increase in memory usage, but hopefully nothing drastic.

  • I think slices and interfaces in Go are both 2×usize width, in which case you just need double-width CAS to make them safe from data races - which most modern architectures support.

    • Slices are base pointer, length, and capacity, so three words. But there's a garbage collector, so you can install a thunk if the slice is updated in a way that torn reads cause problems. It makes reads slightly slower, of course.

      Two-word loads could be used for interface values (assuming that alignment is increased), except if support older x86-64 is needed. There are implementations that require using CMPXCHG16B, which is a really slow way to load two words. Both Intel and AMD updated their ISA manuals that using VMOVDQA etc. is fine (once the CPU supports AVX and the memory is cacheable).

>"I've been seeing C++ fans talk about how they never see memory safety issues in practice in C++ for a decade and a half. I even believed it sometimes. But if there's ever been a common story over those 15 years, it's that these anecdotes mean little, and the actual memory safety property means a lot."

While I use C++ a lot I am not a fan. It is just one of many languages I use. But from my personal experience it is true. I frankly forgot when was the last time I hit memory problem, years for sure. And my code is often a stateful multithreaded backends with high request rate.

  • Are you properly trying to exploit your own software?

    If you're not looking, how would you know?

    You could have a blatant SQL injection in your code and you can always pretend that it doesn't matter, since you haven't been attacked so far.

    • Memory safety issues show up all the time outside of security exploits. Industry began pursuing memory safety long before anyone cared much about security, simply because of the productivity impact of chasing down memory leaks and use-after-free bugs. So if they've used C++ for years without having to do that, its pretty meaningful. It also matches my experience working on a large C++ application that had ubiquitous use of smart pointers. I wouldn't want to do that again, but RAII takes you a long way.

    • >"You could have a blatant SQL injection in your code"

      I my case SQL injection is not possible. I am not constructing any SQL statements from input.

      >"you can always pretend"

      I think it is you pretending to know problems that do not exist in my code.