# Are structs passed by value or by ref?

**URL:** https://discourse.julialang.org/t/are-structs-passed-by-value-or-by-ref/68987
**Category:** New to Julia
**Tags:** struct
**Created:** [September 30, 2021, 10:18am UTC](https://discourse.julialang.org/t/are-structs-passed-by-value-or-by-ref/68987 "2021-09-30T10:18:27Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![whatsthecraic](https://avatars.discourse-cdn.com/v4/letter/w/7bcc69/32.png) [@whatsthecraic](https://discourse.julialang.org/u/whatsthecraic)
#### Post date: [September 30, 2021, 10:18am UTC](https://discourse.julialang.org/t/are-structs-passed-by-value-or-by-ref/68987/1 "2021-09-30T10:18:27Z")

</div>

Hi there,

like the title, are small structs such as

```julia
struct Foo
x::Int64
y::Int64
end

```

allocated in the stack or in the heap, and whether the are passed by ref or by copy to functions?

Moreover, is there a difference in behaviour between mutable and immutable structs?

---

<div class="post-metadata">

### Author: ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)
#### Post date: [September 30, 2021, 10:59am UTC](https://discourse.julialang.org/t/are-structs-passed-by-value-or-by-ref/68987/2 "2021-09-30T10:59:34Z")

</div>

Immutable structs are mostly stack allocated, even if it’s fields are pointers. Semantically both mutable and immutable are passed by reference, but for immutables it doesn’t really matter, since they are immutable.  
Mutable structs generally stay on the heap, and so they have slower performance, specially if you have an array of them, that is because immutable structs can be stored inline in an array, while mutable structs becomes an array of pointers.  
Other threads that went into this are interesting:

> [@Why mutable structs are allocated on the heap?](https://discourse.julialang.org/t/why-mutable-structs-are-allocated-on-the-heap/12992):
>
> From [https://docs.julialang.org/en/latest/manual/types/#Mutable-Composite-Types-1:](https://docs.julialang.org/en/latest/manual/types/#Mutable-Composite-Types-1:) In order to support mutation, such objects are generally allocated on the heap, and have stable memory addresses. If I define: mutable struct MyT x::Int end and then use MyT inside a function, such as: function f(x::Int) q = MyT(x); q.x += 1 return q.x end I would expect q to be allocated on the stack, because it is a local variable that does not change type and MyT is isbits. But it is not: @btime f(1)…

> [@Clarification about memory management of immutable and mutable struct](https://discourse.julialang.org/t/clarification-about-memory-management-of-immutable-and-mutable-struct/31064):
>
> Hello, I’ve been playing around with Julia for awhile and am a big fan of the language overall. Recently, I’ve been doing a bit of work to construct an immutable collections and functional utilities library (work in progress, but source is [here](https://github.com/noahbenson/Air.jl)). A few core pieces are finished at this point so I’ve been testing the performance. Without going into details, what I’ve found is that my persistent dictionary (PDict) has a performance on par with the Julia native Dict type, with respect to haskey, in,…

---

<div class="post-metadata">

### Author: ![giordano](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/giordano/32/2166_2.png) [@giordano](https://discourse.julialang.org/u/giordano)
#### Post date: [September 30, 2021, 11:18am UTC](https://discourse.julialang.org/t/are-structs-passed-by-value-or-by-ref/68987/3 "2021-09-30T11:18:40Z")

</div>

> [@whatsthecraic](#):
>
> and whether the are passed by ref or by copy to functions?

Neither: they’re [passed by sharing](https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing). This is also documented in the manual: [Functions · The Julia Language](https://docs.julialang.org/en/v1/manual/functions/#Argument-Passing-Behavior).

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [September 30, 2021, 1:26pm UTC](https://discourse.julialang.org/t/are-structs-passed-by-value-or-by-ref/68987/4 "2021-09-30T13:26:48Z")

</div>

Although “pass by sharing” is what most people think—completely reasonably, imo, based on the name—that “pass by reference” means. Unfortunately, “pass by reference”, at least in C++, [means something entirely different](https://www.ibm.com/docs/en/zos/2.4.0?topic=calls-pass-by-reference-c-only), which is that you can apply a function to a variable in a calling scope and it can change what value that variable refers to. In sane languages, functions cannot do this at all (macros can though).

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [September 30, 2021, 4:53pm UTC](https://discourse.julialang.org/t/are-structs-passed-by-value-or-by-ref/68987/5 "2021-09-30T16:53:46Z")

</div>

For what is worth, Fortran does that as well:

```fortran
logical function swapnum(i,j)
    integer :: i, j, temp
    temp = i
    i = j
    j = temp
end

program main
    logical :: swapnum, dummy
    integer :: a, b
    a = 10
    b = 20
    dummy = swapnum(a,b) 
    write(*,*) "a is ", a, " and b is ", b
end program main

```

```julia
% ./ref 
 a is 20 and b is 10

```

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [September 30, 2021, 5:00pm UTC](https://discourse.julialang.org/t/are-structs-passed-by-value-or-by-ref/68987/6 "2021-09-30T17:00:19Z")

</div>

Yeah, it was thought to be a good idea once upon a time, along with dynamically scoped local variables, but these days people have generally recognized that it’s a bad idea as it makes it much harder for a person or compiler to reason about what effect code can have on local variables. [This StackOverflow answer](https://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value) has a really good rundown of the meaning and history of these features and terms. These days the most common, standard argument passing behavior is what Lisp (where it originated), Python, Java and Julia all do, which is called “pass by sharing”. A good mental model for this is that all objects are referenced via pointers and those pointers are assigned and passed by value.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [September 30, 2021, 5:03pm UTC](https://discourse.julialang.org/t/are-structs-passed-by-value-or-by-ref/68987/7 "2021-09-30T17:03:07Z")

</div>

More modern Fortran tried to remedy that with the `intent` syntax for the variables, if one declares those variables as `intent(in)` you cannot anymore change their values.
