# Equality of mutable structs

**URL:** <https://discourse.julialang.org/t/equality-of-mutable-structs/107146>\
**Category:** General Usage\
**Tags:** mutable-structure\
**Created:** [December 5, 2023, 7:14am UTC](https://discourse.julialang.org/t/equality-of-mutable-structs/107146 "2023-12-05T07:14:06Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [December 5, 2023, 7:14am UTC](https://discourse.julialang.org/t/equality-of-mutable-structs/107146/1 "2023-12-05T07:14:06Z")

</div>

should this be the case ?

```julia
mutable struct X
    x::Int64
end

X(1)==X(1) #false

```

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [December 5, 2023, 7:16am UTC](https://discourse.julialang.org/t/equality-of-mutable-structs/107146/2 "2023-12-05T07:16:16Z")

</div>

Yes. If you want to compare mutable structs you have to write a function that compares them element wise yourself. I think what you are comparing here are the pointers to the heap where the two structs are stored, and they are different.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [December 5, 2023, 7:21am UTC](https://discourse.julialang.org/t/equality-of-mutable-structs/107146/3 "2023-12-05T07:21:40Z")

</div>

If you need a simple way to compare mutable structs, this package might help: [GitHub - JuliaServices/AutoHashEquals.jl: A Julia macro to add == and hash() to composite types.](https://github.com/JuliaServices/AutoHashEquals.jl)

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [December 5, 2023, 7:25am UTC](https://discourse.julialang.org/t/equality-of-mutable-structs/107146/4 "2023-12-05T07:25:21Z")

</div>

> [@ufechner7](#):
>
> I think what you are comparing here are the pointers to the heap where the two structs are stored

`==` falls back to `===`, which semantically tests for identity, in other words are the 2 arguments bound to the same instance. Since a mutable instance can change its value, even match different instances, its value cannot determine its identity. There isn’t an automatic `==` for field value comparison because of how complicated it gets in the general case, but there’s macros to help.

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [December 5, 2023, 7:38am UTC](https://discourse.julialang.org/t/equality-of-mutable-structs/107146/5 "2023-12-05T07:38:37Z")

</div>

Thanks Uwe, Benny

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [December 5, 2023, 10:35am UTC](https://discourse.julialang.org/t/equality-of-mutable-structs/107146/6 "2023-12-05T10:35:23Z")

</div>

```julia
p = pointer_from_objref(X) # Ptr{Nothing} @0x000001f8aaa5e710
p1 = pointer_from_objref(X(1)) # Ptr{Nothing} @0x000001f8cf9e51f0
p2 = pointer_from_objref(X(1)) # Ptr{Nothing} @0x000001f8ab4ac590

struct Y
    x::Int64
end

pointer_from_objref(Y) # Ptr{Nothing} @0x000001f8cf084cd0
p1=pointer_from_objref(Y(1)) # ERROR: pointer_from_objref cannot be used on immutable objects
p2=pointer_from_objref(Y(1))

Y(1)==Y(1) # true

```

```julia
Get the memory address of a Julia object as a `Ptr`. 
The existence of the resulting `Ptr` will not protect the object 
from garbage collection, so you must ensure that the object
 remains referenced for the whole time that the `Ptr` will be used.

This function may not be called on immutable objects, 
since they do not have stable memory addresses.

```

I’m interested in the topic and despite the answers I’m not sure I fully understand what goes on behind the scenes.  
Even the help documentation for pointer\_from\_objref() doesn’t clarify the situation for me.

I used the pointer\_from\_objref() function to “investigate” a bit but I would need someone to explain or direct to documents where it is explained in more detail what happens.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [December 5, 2023, 11:49am UTC](https://discourse.julialang.org/t/equality-of-mutable-structs/107146/7 "2023-12-05T11:49:13Z")

</div>

`Y` is immutable, so `pointer_from_objref` won’t work. Oftentimes, an immutable type won’t have pointers at all unless its fields hold mutable types. There are some exceptions to that like the unfixed-width `String` (you point to the heap), but even then you still can’t guarantee the address to be stable. Disregarding implementation for a bit, instantiating an immutable type with the [same bits content results in the same instance](https://docs.julialang.org/en/v1/base/base/#Core.:===), semantically. It doesn’t matter if there’s actually multiple copies of `Y(1)`'s data in working memory, it’s all considered the same instance. This allows some implementation optimizations that mutable types don’t have.

---

<div class="post-metadata">

**Author:** ![ctkelley](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ctkelley/32/10684_2.png) [@ctkelley](https://discourse.julialang.org/u/ctkelley)\
**Post date:** [December 5, 2023, 12:40pm UTC](https://discourse.julialang.org/t/equality-of-mutable-structs/107146/8 "2023-12-05T12:40:44Z")

</div>

I got this from Discourse long ago. The `prinln` statement  
is there because I use this mostly for CI.

```julia
#
# ST1 and ST2 must be the same type TS
#
function structeq(ST1, ST2, TS)
eqok=true
for nf in fieldnames(TS)
gx=getfield(ST1,nf); hx =getfield(ST2,nf)
eqok= ((gx==hx) && eqok)
(gx==hx) || println("Difference in field ",nf)
end
return eqok
end

```

For example

```julia
julia> struct bar
       x::Float64
       n::Int64
       end

julia> ST1=bar(1.0,2); ST2=deepcopy(ST1); ST3=bar(2.0,2);

julia> structeq(ST1,ST2,bar)
true

julia> structeq(ST1,ST3,bar)
Difference in field x
false

```

and it works for mutable structs.

```julia
julia> mutable struct foobar
       x::Float64
       n::Int
       end

julia> ST1=foobar(1.0,2); ST2=deepcopy(ST1); 

julia> structeq(ST1,ST2,foobar)
true

julia> ST2.x=3.0;

julia> structeq(ST1,ST2,foobar)
Difference in field x
false

```
