top | item 43333288

(no title)

tyilo | 11 months ago

> Go and Rust are both memory safe.

Go doesn't seem to be memory safe, see https://www.reddit.com/r/rust/comments/wbejky/comment/ii7ak8... and https://go.dev/play/p/3PBAfWkSue3

discuss

order

tptacek|11 months ago

"Memory safety" is a term of art meaning susceptibility to memory corruption attacks. They had to come up with some name for it; that's the name they came up with. This is a perennial tangent in conversations among technologists: give something a legible name, and people will try to axiomatically (re)define it.

Rust is memory safe. Go is memory safe. Python is memory safe. Typescript is memory safe. C++ is not memory safe. C is not memory safe.

dimitropoulos|11 months ago

I love Rust, but you can play exactly the same game with Rust: https://github.com/Speykious/cve-rs

tialaramex|11 months ago

I mean, no? That's basically a known bug in Rust's compiler, specifically it's a soundness hole in type checking, and you'd basically never write it by accident - go read the guts of it for yourself if you think you might accidentally do this.

At some point a next generation solver will make this not compile, and people will probably invent an even weirder edge case for that solver.

Whereas the Go example is just how Go works, that's not a bug that's by design, don't expect Go to give you thread safety that's not what they promised.

vessenes|11 months ago

This is true in that if you pass pointers through go routines, you do not have guarantees about what’s at the end of that pointer. However, this is “by design” in that generally you shouldn’t do that; the overhead the go memory model places on developers is to remember what’s passed as value and what’s passed as a pointer, and act accordingly. The rest it takes care of for you.

The burden placed by rust on the developer is to keep track of all possible mutability and readability states and commit to them upfront during development. (If I may summarize, been a long time since I wrote any Rust). The rest it takes care of for you.

The question of which a developer prefers at a certain skill level, and which a manager of developers at a certain skill level prefers, is going to vary.

jchw|11 months ago

That is not a violation of memory safety, that's a violation of concurrency safety, which Go doesn't promise (and of course, Rust does.)

steveklabnik|11 months ago

Segfaults are very much a memory safety issue. You are correct that concurrency is the cause here, but that doesn't mean it's not a memory safety issue.

That said, most people still call Go memory safe even in spite of this being possible, because, well, https://go.dev/ref/mem

> While programmers should write Go programs without data races, there are limitations to what a Go implementation can do in response to a data race. An implementation may always react to a data race by reporting the race and terminating the program. Otherwise, each read of a single-word-sized or sub-word-sized memory location must observe a value actually written to that location (perhaps by a concurrent executing goroutine) and not yet overwritten. These implementation constraints make Go more like Java or JavaScript, in that most races have a limited number of outcomes, and less like C and C++, where the meaning of any program with a race is entirely undefined, and the compiler may do anything at all.

That last sentence is the most important part. Java in particular specifically defines that tears may happen in a similar fashion, see 17.6 and 17.7 of https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.htm...

I believe that most JVMs implement dynamic dispatch in a similar manner to C++, that is, classes are on the heap, and have a vtable pointer inside of them. Whereas Go's interfaces can work like Rust's trait objects, where they're a pair of (data pointer, vtable pointer). So the behavior we see here with Go is unlikely to be possible in Java, because the tear wouldn't corrupt the vtable pointer, because it's inside what's pointed at by the initial pointer, rather than being right after it in memory.

These bugs do happen, but they have a more limited blast radius than ones in languages that are clearly unsafe, and so it feels wrong to lump Go in with them even though in some strict sense you may want to categorize it the other way.