4 ms·
Is it memory safe? As I understood it you lose that as soon as you start using the namesake keyword, "go".
by srer 4y ago
Is it memory safe? As I understood it you lose that as soon as you start using the namesake keyword, "go".
- matthewmacleod 4y agoYes – Go is generally memory safe, with the exception of the `unsafe` package which is (obviously) not. Outside of this, there is no access to raw pointers or pointer arithmetic. The use of goroutines does not affect memory safety. None of this means that you can't make an absolute mess of concurrency, but that's not a memory safety concern.
- srer 4y agohttps://research.swtch.com/gorace https://research.swtch.com/gorace describes a loss of memory safety through data races, but I note it says "In the current Go implementations" and was written in 2010. I never heard of news that the situation had changed, but if it has I'm most interested in when it did! :)
- jrockway 4y agoIt really depends on where you draw the line. This is an obviously-incorrect program (`++` isn't atomic): func main() { var x, y int64 doneCh := make(chan struct{}) inc := func() { for i := 0; i < 2<<20; i++ { x++ // line 13 in test/main.go atomic.AddInt64(&y, 1) } doneCh <- struct{}{} return } go inc() go inc() <-doneCh <-doneCh fmt.Printf("x, y = %v, %v\n", x, y) } This prints something like: $ go run main.go x, y = 3482626, 4194304 If you run it with the race detector the problem is clear: $ go run -race main.go ================== WARNING: DATA RACE Read at 0x00c0001bc008 by goroutine 7: main.main.func1() /home/jrockway/test/main.go:13 +0x50 Previous write at 0x00c0001bc008 by goroutine 8: main.main.func1() /home/jrockway/test/main.go:13 +0x64 Goroutine 7 (running) created at: main.main() /home/jrockway/test/main.go:19 +0x176 Goroutine 8 (running) created at: main.main() /home/jrockway/test/main.go:20 +0x184 ================== x, y = 4189962, 4194304 Found 1 data race(s) exit status 66 This is not strictly a memory safety problem (this can't crash the runtime), but a program that returns the wrong answer is pretty useless, so there is that. Obviously if x were going to be used as a pointer through the `unsafe` package, you could have problems. (Though I think that x will always be less than y, so if you have proved that memory[base+y] is safe to read, then memory[base+x] is safe to read. But it's easy to imagine a scenario where you overcount instead of undercount.
- samhw 4y agoI'm very confused by this comment. Memory safety doesn't mean "can't crash the runtime"[0]. That would exclude the most basic, canonical examples of memory unsafety: use after free, buffer overwrite/overread, double free, race conditions, etc. The erroneous Go exemplar you posted is literally one of the first examples of memory unsafety on Wikipedia: https://en.wikipedia.org/wiki/Memory_safety https://en.wikipedia.org/wiki/Memory_safety. Go is not memory safe by any stretch of the imagination. It doesn't even claim to be. At most it incidentally prevents a narrow subset of unsafe memory uses, compared with C (not a high standard), in the sense of providing an array type (and concomitant string type) rather than just pointer arithmetic.
- tedunangst 4y agoWriting to a slice concurrently can split the data pointer and capacity, and now you have a pointer that can be accessed out of bounds.