Go atomic store followed by atomic load is behaving erratically across routines - go

I am trying to store a map as unsafe. Pointer and trying to retrieve it later. Below is the code snippet:
package main
import (
"fmt"
"sync/atomic"
"unsafe"
)
type MapHolder struct {
ptr unsafe.Pointer
}
func (m MapHolder) Set(myMap map[string]int64) {
atomic.StorePointer(&m.ptr, unsafe.Pointer(&myMap))
fmt.Printf("The pointer value is: %v\n", atomic.LoadPointer(&m.ptr))
}
func (m MapHolder) Get() map[string]int64 {
ptr := atomic.LoadPointer(&m.ptr)
if ptr == nil {
fmt.Printf("Why is this pointer value nil?")
return nil
} else {
return *(*map[string]int64)(ptr)
}
}
func main() {
var m MapHolder
test := make(map[string]int64)
test["hello"] = 1
m.Set(test)
m.Get()
}
When Set(), executes, it prints the contents of m.ptr correctly. However, when we do a Get(), it returns nil. This looks totally un-expected to me. I am using go 1.11.6
The output of the above program is:
The pointer loaded is: 0x40c130
Why is this pointer value nil?

Because the Set method has a value receiver, the receiver value and any changes to the value are discarded when the method returns. Fix the problem by using pointer receivers.
func (m *MapHolder) Set(myMap map[string]int64) { ... }
func (m *MapHolder) Get() map[string]int64 { ... }
The Get method must also use a pointer receiver to prevent a data race on the copy of the receiver argument.
The Set method stores the address of argument myMap, not the address of m in main. This may or may not be a problem depending on how the application uses MapHolder.

Related

Uninitialized Embedded Struct

I'm a bit perplexed by this go code. I have a struct (Outer) with an embedded struct (Inner), but when I initialize Outer, I intentionally leave the embedded struct uninitialized.
type Inner struct {
value int
}
func (i *Inner) MyFunc() string {
return "inner"
}
func (i *Inner) OnlyInner() string {
return "only inner stuff"
}
type Outer struct {
*Inner
}
func (o *Outer) MyFunc() string {
return "outer"
}
func main() {
// embedded struct is *not* initialized
o := &Outer{}
fmt.Println(o.Inner)
fmt.Println(o.Inner.MyFunc())
fmt.Println(o.Inner.OnlyInner())
//fmt.Println(o.Inner.value)
}
Output:
<nil>
inner
only inner stuff
And if I uncomment the last line (with o.Inner.value), I get a nil pointer dereference error.
What's up here? The effective go page says (https://golang.org/doc/effective_go.html#embedding):
When we embed a type, the methods of that type become methods of the outer type, but when they are invoked the receiver of the method is the inner type, not the outer one.
It seems like in my case, the inner type is <nil>, yet the method calls execute without problem. What's going on under the hood?
A method can be called with a nil receiver, as long as you do not dereference the receiver itself.
This means that the following works playground:
package main
import (
"fmt"
)
type foo struct {
val int
}
func (f *foo) Print() {
fmt.Println("Receiver:", f)
}
func (f *foo) PrintVal() {
fmt.Println("Val: ", f.val)
}
func main() {
var f *foo
f.Print()
//f.PrintVal()
}
f.Print() works without issues since we're just printing a pointer, we're not trying to dereference it.
However, f.PrintVal attempts to dereference a nil pointer, causing a panic.
When in doubt, remember that the methods in this example are equivalent to functions that take the receiver as first parameter:
func Print(f *foo)
func PrintVal(f *foo)
This is mentioned in the spec under method declarations:
The type of a method is the type of a function with the receiver as
first argument. For instance, the method Scale has type
func(p *Point, factor float64)
However, a function declared this way
is not a method.
This makes it clear that the receiver is nothing special, it can be nil as long as you don't dereference it.
The methods of the uninitialized struct are being called with a nil-receiver. If in the methods used that receiver you would get a panic. It is valid to call a method using a nil receiver, and the method could modify its behavior by checking if the receiver is nil.

Is empty interface in golang as function argument is Pass by Value or pointer

If I have function like this
func TestMethod ( d interface{} ) {
}
If I am calling this as
TestMethod("syz")
Is this pass by value or pass by pointer ?
To summarise some of the discussion in the comments and answer the question:
In go everything in Go is passed by value. In this case the value is an interface type, which is represented as a pointer to the data and a pointer to the type of the interface.
This can be verified by running the following snippet (https://play.golang.org/p/9xTsetTDfZq):
func main() {
var s string = "syz"
read(s)
}
//go:noinline
func read(i interface{}) {
println(i)
}
which will return (0x999c0,0x41a788), one pointer to the data and one pointer to the type of interface.
Updated: Answer and comments above are correct. Just a lite bit of extra information.
Some theory
Passing by reference enables function members, methods, properties,
indexers, operators, and constructors to change the value of the
parameters and have that change persist in the calling environment.
Little code sniped to check how function calls work in GO for pointers
package main_test
import (
"testing"
)
func MyMethod(d interface{}) {
// assume that we received a pointer to string
// here we reassign pointer
newStr := "bar"
d = &newStr
}
func TestValueVsReference(t *testing.T) {
data := "foo"
dataRef := &data
// sending poiner to sting into function that reassigns that pointer in its body
MyMethod(dataRef)
// check is pointer we sent changed
if *dataRef != "foo" {
t.Errorf("want %q, got %q", "bar", *dataRef)
}
// no error, our outer pointer was not changed inside function
// confirms that pointer was sent as value
}

Strange behavior for a pointer of an interface

I wrote 3 similar functions to figure out a strange behavior of Go's pointer reflection.
package main
import (
"reflect"
"fmt"
)
var i interface{} = struct {}{} // i is an interface which points to a struct
var ptr *interface{} = &i // ptr is i's pointer
func f(x interface{}) { // print x's underlying value
fmt.Println(reflect.ValueOf(x).Elem())
}
func main1() { // f is asking for interface? OK, I'll use the struct's interface
structValue := reflect.ValueOf(ptr).Elem().Elem().Interface()
f(structValue)
}
func main2() { // Error? Let me try the struct's pointer
structPtr := reflect.ValueOf(ptr).Elem().Interface()
f(structPtr)
}
func main3() { // Why this one could succeed after New() ?
typ := reflect.ValueOf(ptr).Elem().Elem().Type()
newPtr := reflect.New(typ).Elem().Addr().Interface()
f(newPtr)
}
func main() {
//main1() // panic: reflect: call of reflect.Value.Elem on struct Value
//main2() // panic: reflect: call of reflect.Value.Elem on struct Value
main3() // OK. WHY???
}
Only main3 is working, the other 2 would panic. Why?
The key difference of 3 is that it creates a New Value.
As to main2, I think ValueOf().Elem().Interface() has already reconstructed a interface which points at the struct{}{}, just don't understand why it would fail.
The value returned from reflect.ValueOf holds the concrete value stored in the argument. If the argument is nil, the zero reflect.Value is returned.
To put this another way, the reflect.Value and the interface passed to reflect.Value have the same underlying value.
The functions main1 and main2 will work as I think you expect if you f change to:
func f(x interface{}) { // print x's underlying value
fmt.Println(reflect.ValueOf(x))
}
The argument to f in main3 is a *struct{}. The function f dereferences the pointer (with the call to Elem()) and prints the reflect value for the struct{}.
One point that might be confusing is that reflect.ValueOf(ptr).Elem().Elem().Interface() and reflect.ValueOf(ptr).Elem().Interface() return an interface with the same concrete value.
The expression reflect.ValueOf(ptr).Elem() is the reflect value corresponding to i. The call to Interface() on this value returns an interface with the concrete value in i.
The expression reflect.ValueOf(ptr).Elem().Elem() is the reflect value corresponding to i's concrete value. The call to Interface() on this value returns an interface containing that concrete value.

Confusing for these pieces of code of interface implementation and calling?

Version of Go
go version go1.11 darwin/amd64
Code 1:
package main
import "fmt"
type myintf interface {
GotU()
}
type esc struct {
i int
}
//func GotU(t esc);
func (e esc)GotU() {
e.i = 10
}
func TestFunc(it myintf) string {
it.GotU()
return "kk"
}
func main() {
var test esc
test.i = 9
TestFunc(test)
fmt.Println(test.i)
}
Code 2:
package main
import "fmt"
type myintf interface {
GotU()
}
type esc struct {
i int
}
func (e esc)GotU() {
e.i = 10
}
func TestFunc(it myintf) string {
it.GotU()
return "kk"
}
func main() {
var test esc
test.i = 9
TestFunc(&test)
fmt.Println(test.i)
}
Code 3:
package main
import "fmt"
type myintf interface {
GotU()
}
type esc struct {
i int
}
func (e *esc)GotU() {
e.i = 10
}
func TestFunc(it myintf) string {
it.GotU()
return "kk"
}
func main() {
var test esc
test.i = 9
TestFunc(test)
fmt.Println(test.i)
}
The outputs:
code 1 output: 9
code 2 output: 9
code 3 cannot be compiled due to a type mismatch
Since only func (e esc)GotU() implemented, why should both pieces of code work and deliver the same result?
It's kind of confusing for me to pass a pointer of struct to that function (TestFunc) to get the same answer.
The last code snippet has implemented a method receiver of pointer type. This will consider the situation if you want to modify the value of receiver.
func (e *esc) GotU() {
e.i = 10
}
In above case Since you are passing pointer type receiver on a method which is implementing the interface.
type myintf interface {
GotU()
}
So you need to pass address of struct in TestFunc. This is the reason you are getting type mismatch error, because you are passing variable of esc type while your method requires variable of *esc.
func main() {
var test esc
test.i = 9
TestFunc(&test)
fmt.Println(test.i)
}
Working example on Go playground
In Golang there are two ways to pass a method receiver.
func (s *MyStruct) pointerMethod() { } // method on pointer
func (s MyStruct) valueMethod() { } // method on value
For programmers unaccustomed to pointers, the distinction between
these two examples can be confusing, but the situation is actually
very simple. When defining a method on a type, the receiver (s in the
above examples) behaves exactly as if it were an argument to the
method. Whether to define the receiver as a value or as a pointer is
the same question, then, as whether a function argument should be a
value or a pointer. There are several considerations
First, and most important, does the method need to modify the receiver? If it does, the receiver must be a pointer. (Slices and maps act as references, so their story is a little more subtle, but for instance to change the length of a slice in a method the receiver must still be a pointer.) In the examples above, if pointerMethod modifies the fields of s, the caller will see those changes, but valueMethod is called with a copy of the caller's argument (that's the definition of passing a value), so changes it makes will be invisible to the caller.
The difference between the 1st and second version is, that you pass the struct directly in one version and the pointer to the struct in the other version. In this case these programs work the same, as the pointer also includes the all defined funcs on the struct.
But this does not work the other way around. You define the method GotU on the pointer receiver. The struct does not know about this func. If you would call
TestFunc(&test)
in the third program, it would compile but work differently than the other two: The output is: "10"
As the GotU is defined on the pointer receiver test is passed as reference and the modifications persist. In the other programs test is passed as value, i.e. it is copied, the copy is modified in GotU. When the func exits, the copy is discarded and the old version is still the same as before.

Passing pointer to string when the function takes an interface?

I am passing a pointer to a string, to a method which takes an interface (I have multiple versions of the method, with different receivers, so I am trying to work with empty interfaces, so that I don't end up with a ton of boilerplate madness. Essentially, I want to populate the string with the first value in the slice. I am able to see the value get populated inside the function, but then for some reason, in my application which calls it, tha value doesn't change. I suspect this is some kind of pointer arithmetic problem, but could really use some help!
I have the following interface :
type HeadInterface interface{
Head(interface{})
}
And then I have the following functions :
func Head(slice HeadInterface, result interface{}){
slice.Head(result)
}
func (slice StringSlice) Head(result interface{}){
result = reflect.ValueOf(slice[0])
fmt.Println(result)
}
and... here is my call to the function from an application which calls the mehtod...
func main(){
test := x.StringSlice{"Phil", "Jessica", "Andrea"}
// empty result string for population within the function
var result string = ""
// Calling the function (it is a call to 'x.Head' because I lazily just called th import 'x')
x.Head(test, &result)
// I would have thought I would have gotten "Phil" here, but instead, it is still empty, despite the Println in the function, calling it "phil.
fmt.Println(result)
}
*NOTE : I am aware that getting the first element doesn't need to be this complicated, and could be slice[0] as a straight assertion, but this is more of an exercise in reusable code, and also in trying to get a grasp of pointers, so please don't point out that solution - I would get much more use out of a solution to my actual problem here * :)
As you said in your NOTE, I'm pretty sure this doesn't have to be this complicated, but to make it work in your context:
package main
import (
"fmt"
"reflect"
)
type HeadInterface interface {
Head(interface{})
}
func Head(slice HeadInterface, result interface{}) {
slice.Head(result)
}
type StringSlice []string
func (slice StringSlice) Head(result interface{}) {
switch result := result.(type) {
case *string:
*result = reflect.ValueOf(slice[0]).String()
fmt.Println("inside Head:", *result)
default:
panic("can't handle this type!")
}
}
func main() {
test := StringSlice{"Phil", "Jessica", "Andrea"}
// empty result string for population within the function
var result string = ""
// Calling the function (it is a call to 'x.Head' because I lazily just called th import 'x')
Head(test, &result)
// I would have thought I would have gotten "Phil" here, but instead, it is still empty, despite the Println in the function, calling it "phil.
fmt.Println("outside:", result)
}
The hard part about working with interface{} is that it's hard to be specific about a type's behavior given that interface{} is the most un-specific type. To modify a variable that you pass as a pointer to a function, you have to use the asterisk (dereference) (for example *result) on the variable in order to change the value it points to, not the pointer itself. But to use the asterisk, you have to know it's actually a pointer (something interface{} doesn't tell you) so that's why I used the type switch to be sure it's a pointer to a string.

Resources