Hello everyone.
I have a question about a common programming error I have made several
times. It regards the use of a pointer to a loop variable outside of the
loop. Basically, we want to convert a slice, map, or channel of items (the
source sequence) into a map, slice, or channel of pointers to respective
items in the source sequence. But, rather than point to the actual values,
we point to the loop variable.
I have written some code in a GitHub gist to demonstrate this mistake
<https://gist.github.com/barisere/408fbfb4a0f024bcafced1bf99544b27>. I
think this mistake can be caught by code analysis tools, but I don't know
of any that catches these. If there is any, please let me know so that I
can save my future self some unnecessary trouble. If there isn't, how can I
make one (probably add it to vet)?
Here's the code sample, if you prefer to read it all here.
// escape_test.go
package main_test
import (
"testing"
"testing/quick"
"unsafe"
)
func all(xs []*int, f func(x *int) bool) (result bool) {
result = true
for _, v := range xs {
result = result && f(v)
}
return result
}
func Test_references_to_loop_variable_outside_the_loop_have_same_value(t
*testing.T) {
f := func(xs []int) bool {
var loopVariableAddress uintptr
var zeroOfUintptr uintptr
var copies = make([]*int, 0, len(xs))
for _, x := range xs {
if loopVariableAddress == zeroOfUintptr {
// Store the loop variable's address for later comparison.
loopVariableAddress = uintptr(unsafe.Pointer(&x))
}
// Copy the address of x into a slice.
copies = append(copies, &x)
// The append statement above is most likely a mistake.
// We probably mean
// copies = append(copies, &xs[index]);
// assuming `index` is the ignored loop index.
}
return all(copies, func(x *int) bool {
// All values in `copies` are the same pointer address.
return uintptr(unsafe.Pointer(x)) == loopVariableAddress && *x
== *copies[0]
})
}
if err := quick.Check(f, nil); err != nil {
t.Fatal(err)
}
}
--
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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/cfbc843b-2acf-4440-81d2-01ab68a6628bn%40googlegroups.com.