# Puzzling behavior of "wrong" inner constructor

**URL:** <https://discourse.julialang.org/t/puzzling-behavior-of-wrong-inner-constructor/89954>\
**Category:** General Usage\
**Tags:** struct, constructors\
**Created:** [November 8, 2022, 9:25pm UTC](https://discourse.julialang.org/t/puzzling-behavior-of-wrong-inner-constructor/89954 "2022-11-08T21:25:40Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![simsurace](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simsurace/32/30216_2.png) [@simsurace](https://discourse.julialang.org/u/simsurace)\
**Post date:** [November 8, 2022, 9:25pm UTC](https://discourse.julialang.org/t/puzzling-behavior-of-wrong-inner-constructor/89954/1 "2022-11-08T21:25:40Z")

</div>

Today I was quite surprised by this mistake of mine in an inner constructor not throwing an error, but leading to a silent bug. My actual case had many arguments and I missed several, but here is a MWE:

```julia
julia> struct MyStruct{T}
           x::Float64
           MyStruct(x) = new{typeof(x)}() # forgot to put an argument here
       end

julia> s = MyStruct(1.0)
MyStruct{Float64}(1.0) # why did this work?

julia> s = MyStruct(1)
MyStruct{Int64}(6.9311367529162e-310) # where did this come from?

```

I guess the obvious takeaway is that one should always unit test the behavior of a custom inner constructor.

But I would have expected that calling a zero-argument `new` for this struct would throw an error, since the struct has a field.  
Could someone explain the reasoning behind this?

---

<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:** [November 8, 2022, 9:33pm UTC](https://discourse.julialang.org/t/puzzling-behavior-of-wrong-inner-constructor/89954/2 "2022-11-08T21:33:32Z")

</div>

You can call `new()` with fewer arguments than the struct has fields and those fields will be uninitialized. For reference type fields that are represented as pointers, these appear as `undef` which is a non-value that’s an error to access in any way. For value type fields like you have here, the uninitialized fields will contain uninitialized memory, so basically just some random junk. (This junk value looks like it could maybe be a pointer reinterpreted as a float.)

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [November 8, 2022, 9:38pm UTC](https://discourse.julialang.org/t/puzzling-behavior-of-wrong-inner-constructor/89954/3 "2022-11-08T21:38:54Z")

</div>

> [@simsurace](#):
>
> But I would have expected that calling a zero-argument `new` for this struct would throw an error, since the struct has a field.

Nope, it’s always allowed to call `new()` – it leaves all of the fields uninitialized. Admittedly that’s not often something you need to do in Julia (unlike C++ where it comes up all the time), but it’s a valid thing to do.

The fact that `MyStruct(1.0)` appears to work is actually really neat. The value of `x` is uninitialized (it’s just random garbage), but it seems to happen that Julia is re-using memory which contained that 1.0 for its uninitialized garbage. You get different uninitialized garbage when you pass `1`, but it’s all just undefined behavior.

For example, passing a float64 gives yet other uninitialized garbage when in a function:

```julia
julia> function f()
         x = 1.0
         MyStruct(x)
       end
f (generic function with 1 method)

julia> f()
MyStruct{Float64}(6.9357062358239e-310)

```

So the fact that you got `MyStruct{Float64}(1.0)` back at the REPL is just a coincidence.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [November 8, 2022, 9:56pm UTC](https://discourse.julialang.org/t/puzzling-behavior-of-wrong-inner-constructor/89954/4 "2022-11-08T21:56:24Z")

</div>

Referencing [Warn on uninitialized isbits-fields in structs? · Issue #24943 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/24943).

---

<div class="post-metadata">

**Author:** ![simsurace](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simsurace/32/30216_2.png) [@simsurace](https://discourse.julialang.org/u/simsurace)\
**Post date:** [November 9, 2022, 6:58am UTC](https://discourse.julialang.org/t/puzzling-behavior-of-wrong-inner-constructor/89954/5 "2022-11-09T06:58:08Z")

</div>

Thanks for the explanations. I now see that this is mentioned in the manual. I think it is something that can happen accidentally, so while I’m probably not going to run into it myself again, I would also welcome a warning for new users as proposed in the linked issue.
