## Issue

I’ve been using `reflect.DeepEqual`

to deeply compare structs using circular pointers. As that does not work with maps and for better test output, I’ve switched to `go-cmp`

.

Now I had to take note that even though `cmp.Equal`

is supposed to be a drop-in replacement for `reflect.DeepEqual`

, in cases where the former works correctly, there’s a different result in this case, even though it actually is deeply equal.

Can anyone tell me why the result is different in this case and ideally, how to fix it?

Code in Go playground: https://play.golang.com/p/rLWKwMlAfwu

(Updated to use fmt.Printf(), because I couldn’t get `testing`

running in playground)

Output for diff:

```
StrongConnect() mismatch (-want +got):
&⟪ref#0⟫main.Edge{
StartNode: &⟪ref#1⟫main.Node{
Variable: 1,
- Low: &⟪ref#0: 0xc00005c120⟫(...),
+ Low: &⟪ref#0: 0xc00005c120⟫(...),
High: &{StartNode: &⟪ref#1⟫(...), EndNode: &{Variable: 2}, EdgeType: 1, Weight: 1},
},
EndNode: &{Variable: 2},
EdgeType: 0,
Weight: 1,
}
```

## Solution

`reflect.DeepEqual`

is more lax than `cmp.Equal`

when comparing structures with cycles (and arguably incorrect).

`cmp.Equal`

will only consider overlapping graphs equivalent if the set of nodes and edges in the graph is the same. *Note*: Both `Node`

and `Edge`

structs are nodes in this graph comparison.

In your example, the 2 graphs/structs overlap but `wantEdge0`

is has an extra `Edge`

struct as the root node (prepended).

Here is cut down representation of the cycles in your data structures:

```
wantEdge0 := &main.Edge{ // n0
StartNode: &main.Node{ // n1
Low: &main.Edge{} // n2
},
}
wantEdge0.StartNode.Low.StartNode = wantEdge0.StartNode // n1
got := wantEdge0.StartNode.Low // n2
```

Hence there are the 2 different cycles:

`wantEdge0 [n0] -> wantEdge0.StartNode [n1] -> got [n2] -> wantEdge0.StartNode [n1]`

`got [n2] -> wantEdge0.StartNode [n1] -> got [n2]`

Here is a simple example that demonstrates this difference between `reflect.DeepEqual`

and `cmp.Equal`

:

```
package main
import (
"fmt"
"reflect"
"github.com/google/go-cmp/cmp"
)
type Node struct {
Next *Node
Value int
}
func main() {
a0 := &Node{}
a1 := &Node{}
a2 := &Node{}
a0.Next = a1
a1.Next = a2
a2.Next = a1
b1 := &Node{}
b2 := &Node{}
b1.Next = b2
b2.Next = b1
fmt.Println("DeepEqual\tcmp.Equal")
fmt.Printf("\t%v\t%v\t\tIndependent graphs\n", reflect.DeepEqual(a1, b1), cmp.Equal(a1, b1))
fmt.Printf("\t%v\t%v\t\tSame graph, different root\n", reflect.DeepEqual(a1, a2), cmp.Equal(a1, a2))
fmt.Printf("\t%v\t%v\t\tSame graph prepend vs no prepend\n", reflect.DeepEqual(a0, a1), cmp.Equal(a0, a1))
}
```

Output:

```
$ ./compare
DeepEqual cmp.Equal
true true Independent graphs
true true Same graph, different root
true false Same graph prepend vs no prepend
```

**Solution**: I would recommend allocating completely separate structures for your *want* struct and the test input. This way the *want* and *got* structs won’t overlap and they should compare as intended.

References:

- https://github.com/google/go-cmp/commit/5a6f75716e1203a923a78c9efb94089d857df0f6
- https://github.com/google/go-cmp/issues/74

Answered By – mpx

Answer Checked By – Willingham (GoLangFix Volunteer)