In Go, pointers (mostly) don't go with slices in practice
utcc.utoronto.ca
In Go, pointers (mostly) don't go with slices in practice
1–10 of 98 posts
Re: In Go, pointers (mostly) don't go with slices in practice
#2Re: In Go, pointers (mostly) don't go with slices in practice
#3In Go, you get a stable version of the old data, and the garbage collector tracks that you still have a reference to it. This is safe, but confuses some people.
In Rust, the borrow checker won't let you modify the array while you have a reference to a slice of it. So you can't do this at all.
In C++, you get a mention on the Department of Homeland Security's US-CERT site.
Re: In Go, pointers (mostly) don't go with slices in practice
#4Incidentally, this is equally true of creating additional pointers or slices pointing into an growable array. They aren’t safe after the next append(). If you grow an array then you need to refer to its elements using array indices.
But if you have a fixed-length array, or between appends, you can use both pointers and slices to point to parts of it, and it will work fine,
This all works the same as C if you think of a slice as a glorified pointer. If you’re thinking of a slice as a JavaScript array then you’ll have trouble.
Re: In Go, pointers (mostly) don't go with slices in practice
#5 When you take a pointer to a slice, you get a pointer to the current version of this tuple of information for the slice. This pointer may or may not refer to a slice that anyone else is using; for instance:
ps := &s
s = append(s, 50)
At this point, '*ps' may or may not be the same thing as 's', and so it might or might not have the new '50' element at the end.
No, *ps will always be the same as s, because ps is a pointer so it carries no information other than the address of s.The author seems to have failed to distinguish the operation of copying a fat pointer (which opens the possibility of divergence) and the operation of the taking the address of a fat pointer (which involves no copying, so divergence is not possible - where would the divergent version be stored?).
See this code snippet: https://play.golang.org/p/tdb-O8a6hDN
Re: In Go, pointers (mostly) don't go with slices in practice
#6I think it works in the same way as a pointer to std::span in C++. (Or pointer to std::string_view with the exception that std::string_view doesn't allow modification of the elements.)
I guess the difference is that std::span doesn't let you append to the backing array through the std::span directly. So with C++ you have to write more code which makes it clearer what's happening.
Re: In Go, pointers (mostly) don't go with slices in practice
#7The author seems confused. The following is simply not true: When you take a pointer to a slice, you get a pointer to the current version of this tuple of information for the slice. This pointer may or may not refer to a slice that anyone else is using; for instance: ps := &s s = append(s, 50) At this point, '*ps' may or may not be the same thing as 's', and so it might or might not have the new '50' element at the e…
s is a local variable (or global, doesn't matter). ps simply points to that local variable. You can modify the local variable all day long and ps will still point to it, not some old version of it.
Re: In Go, pointers (mostly) don't go with slices in practice
#8Problems with memory addressing are bound to happen with asynchronous memory manipulation: threads in C/C++ or concurrent GC in go. The biggest issue here is that memory manipulation happens behind the scenes and the runtime does not offer effective tools to synchronise memory state manipulations.
The GC only operates on “dead” allocations (afaik it remains non-moving) so it’s not a concern for now.
Re: In Go, pointers (mostly) don't go with slices in practice
#9> To programmers from other languages, such as C or C++, the concept of pointers to dynamically extensible arrays seems like a perfectly decent idea
Write Go in Go, don’t write C in Go. (Which applies to every language, tbh.)
Re: In Go, pointers (mostly) don't go with slices in practice
#10Well, of course slices work that way. Think about what happens if you have a reference to a slice in an array and you shrank the array to 0. You've just created a dangling pointer. In Go, you get a stable version of the old data, and the garbage collector tracks that you still have a reference to it. This is safe, but confuses some people. In Rust, the borrow checker won't let you modify the array while you have a re…
Rust has created a weird perception that memory safety equals safety. Language is a tool and it should work with me: it is extremely important that my understanding of what the program should do aligns with what it actually does.
The way you describe go's behavior is "takes snapshot of the underlying data", which usually means "deep copy container". Taking a pointer/reference usually means quite an opposite. So it is "safe" in a sense that the pointer points to valid data, but is "incorrect" in a sense that it does wrong thing without warning.
Sure, one could argue that value-returning modification functions are a giveaway of invalidated data. But this is not C, go has reference counting and instead of "forcing" underlying array to maintain the same address it just keeps original pointer pointing to dereferenceable, but wrong data.