# sizeof(MVector{N, T}) where T \<: costomStructure returns unexpected values

**URL:** https://discourse.julialang.org/t/sizeof-mvector-n-t-where-t-costomstructure-returns-unexpected-values/100768
**Category:** New to Julia
**Created:** [June 24, 2023, 1:25am UTC](https://discourse.julialang.org/t/sizeof-mvector-n-t-where-t-costomstructure-returns-unexpected-values/100768 "2023-06-24T01:25:58Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Kadii](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@Kadii](https://discourse.julialang.org/u/Kadii)
#### Post date: [June 24, 2023, 1:25am UTC](https://discourse.julialang.org/t/sizeof-mvector-n-t-where-t-costomstructure-returns-unexpected-values/100768/1 "2023-06-24T01:25:58Z")

</div>

I’m working on building a custom binary file reader using [StaticArrays](https://github.com/JuliaArrays/StaticArrays.jl). In the reader, I would like to use the custom structure (`TestS2`) that contains a `MVector` of another custom structure (`TestS1`).  
To get the byte size of the structures, I also defined the custom `sizeof` function. This function returns just fine for `TestS1` but `TestS2`. Does anyone help me to make it worked?

Please see the following code.

```julia
using StaticArrays

abstract type AbsBinType end

mutable struct TestS1 <: AbsBinType
	p1::MVector{2, UInt8}
	p2::Int32
	TestS1() = new()
end

mutable struct TestS2{N} <: AbsBinType
	q1::UInt8
	q2::MVector{N, TestS1}
	TestS2{N}() where N = new()
end

import Base: sizeof
sizeof(s::Type{T}) where T <: AbsBinType = sum(sizeof.(fieldtypes(s)))

sizeof(TestS1)
    6

sizeof(TestS2{3}) # this should return 1 + 6 * 3 = 19
    25

```

* * *

I think this is not directly related to this post but this is how I would like to use `AbsBinType` for binary file reading.

```julia
function read(io::IO, s::Type{T}) where T <: AbsBinType 
	N = fieldcount(s)
	readStruct = s()
	for n in 1:N
		setproperty!(readStruct, fieldnames(s)[n], read(io, fieldtypes(s)[n]))
	end
	return readStruct
end

```

* * *

I found this post. This is similar to what I would like to ask but they use immutable static vector with primitive types.

> [@Unexpected \`sizeof\` struct with long StaticArrays](https://discourse.julialang.org/t/unexpected-sizeof-struct-with-long-staticarrays/79797):
>
> Consider this: using StaticArrays struct Dummy B::SVector{34,UInt8} end @assert sizeof(Dummy) == sum(sizeof.(fieldtypes(Dummy))) struct Dummy32 A::Float32 B::SVector{32,UInt8} end @assert sizeof(Dummy32) == sum(sizeof.(fieldtypes(Dummy32))) struct Dummy34 A::Float32 B::SVector{34,UInt8} end @assert sizeof(Dummy34) == sum(sizeof.(fieldtypes(Dummy34))) The last assertion fails, sizeof(Dummy34) return 40, 2 more bytes than expected. The behavior switched based on number of …

---

<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: [June 24, 2023, 3:30am UTC](https://discourse.julialang.org/t/sizeof-mvector-n-t-where-t-costomstructure-returns-unexpected-values/100768/2 "2023-06-24T03:30:42Z")

</div>

Check `sizeof(MVector{3, TestS1})`, it should have run in your `sizeof(TestS2{3})` call.

Also don’t implement `sizeof` yourself, it’ll be done for your composite types automatically and it takes into account the byte alignment of your system. You’ll see if you rerun the session without your own methods.

PS You don’t need the `where N` in your struct definition, `{N}` in the struct definition _is_ the `where` clause. See, this would work: `abstract type A end; mutable struct subA{N} <: A end`. I really don’t know why you were even allowed to write the `where N`, it does nothing, not even throw errors `mutable struct subA2{N} <: A where VarDoesNotExist end`.

---

<div class="post-metadata">

### Author: ![Kadii](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@Kadii](https://discourse.julialang.org/u/Kadii)
#### Post date: [June 24, 2023, 4:15am UTC](https://discourse.julialang.org/t/sizeof-mvector-n-t-where-t-costomstructure-returns-unexpected-values/100768/3 "2023-06-24T04:15:19Z")

</div>

Thank you for your feedback. Somehow I left `where N` in the struct definition from my code. I edited my post.

I checked the `sizeof(MVector{3, TestS1})` did not use the `sizeof` I defined. That would be very helpful if you give me the answers to my questions listed below.

1. What does the byte alignment of the system?  
If I overwrite the `sizeof` for my custom structure, does this influence the code performance or cause the crash of the program?
2. Is it possible to define the a new function to compute the byte size of `MVector{3, TestS1}`?  
If so, I will be able to define different name functions to compute the sizes.

---

<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: [June 24, 2023, 6:36am UTC](https://discourse.julialang.org/t/sizeof-mvector-n-t-where-t-costomstructure-returns-unexpected-values/100768/4 "2023-06-24T06:36:19Z")

</div>

> [@Kadii](#):
>
> I checked the `sizeof(MVector{3, TestS1})` did not use the `sizeof` I defined.

Of course not, you defined a `sizeof` method for subtypes of `AbsBinType`, so the `MVector` does not involve it.

> [@Kadii](#):
>
> What does the byte alignment of the system?

The [wikipedia article](https://en.wikipedia.org/wiki/Data_structure_alignment) probably does a better job than me, but I’ll try to explain it fast. You’ve heard of 32-bit vs 64-bit architecture, those are word sizes that the machine does memory reads/writes most efficiently. So, types are often arranged to fit in full words by being padded to full words or smaller powers of 2 bytes (1, 2, 4) that add up to a full word. 6 bytes was not a power of 2, so it was padded to 8 bytes. The Julia compiler does this automatically.

> [@Kadii](#):
>
> If I overwrite the `sizeof` for my custom structure, does this influence the code performance or cause the crash of the program?

You really don’t want to do it because it misleads you how much space the instance is taking up. `TestS1`’s data uses 6 bytes, but it is aligned to take up 8 at a time. You don’t want `sizeof` to give you the wrong numbers, that’s why it’s automatically defined when the struct is defined.

---

<div class="post-metadata">

### Author: ![Kadii](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@Kadii](https://discourse.julialang.org/u/Kadii)
#### Post date: [June 25, 2023, 6:23pm UTC](https://discourse.julialang.org/t/sizeof-mvector-n-t-where-t-costomstructure-returns-unexpected-values/100768/5 "2023-06-25T18:23:42Z")

</div>

Thank you for your kind explanations. That’s really helpful to understand!

I defined functions, `bytesize`, instead of overwriting `sizeof`.

```julia
bytesize(T::DataType) = sizeof(T)
bytesize(::Type{T}) where T <: AbsBinType = sum(bytesize.(fieldtypes(T)))
bytesize(::Type{MVector{N, T}}) where {N, T <: AbsBinType} = bytesize(T) * N

bytesize(TestS1)
    6
bytesize(TestS2{3})
    19

```

This is working fine for my usage. Thank you for your kindness.
