On Tue, Jan 30, 2018 at 9:10 AM, Dmitriy Cherchenko <dcherche...@gmail.com> wrote:
> It looks like the language spec is a little imprecise in the Order of > evaluation <https://golang.org/ref/spec#Order_of_evaluation> section > about if any function evaluating an index of a slice will always be invoked > before anything is done to the slice at that index. That is, if you have > something like: > mySlice[someFunc()] = 45 > is someFunc() guaranteed to be called before the value at the int it > returns is set to 45? > I don't understand this question. How could it possibly not be? It has to be evaluated to know what value it returns? I created a sample test and ran it on 32 different kinds of machines (using > Travis CI), including 8 different versions of Go, two different > architectures, and two operating systems. > > Here is the code: https://github.com/dchenk/go-eval-order > > And here are the test results: https://travis-ci.org/dchenk/go-eval-order/ > builds/335042572 > FWIW, the failing test cases seem to be flakes - i.e. they are timed out builds, not actual test failures? So what are the guarantees, if there are any, about the evaluation order of > the inner function verses the slice indexing operation? I want to make sure > invalid indexing isn't possible in the kind of code on line 10 in the > main.go file in the repo linked to above. > >From my reading of the spec, I'd argue that the code is potentially incorrect, but I'm having trouble parsing your question above into what I consider a potential failure scenario. For the line b.data[b.grow()] = bt the spec explicitly makes no guarantees about the evaluation order of b.data, b.grow, b.grow() and bt, as it only orders function/method/communication calls among each other. These are roughly the evaluations that happen: 1. n := b.grow() 2. s := b.data 3. s[n] = bt However, this would also be valid (from my reading of the spec): 1. s := b.data 2. n := b.grow() 3. s[n] = bt In that case, s might have a stale copy of the slice, from before the append. To fix that, you should split that into two lines: func (b *Buf) WriteByte(bt byte) { n := b.grow() b.data[n] = bt } Hope that helps. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.