# Using a variant in an stl container initialised at global scope crashes

**URL:** <https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595>\
**Category:** General JUCE discussion\
**Created:** [March 31, 2017, 4:14pm UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595 "2017-03-31T16:14:23Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![jamiebullock](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jamiebullock/32/459_2.png) [@jamiebullock](https://forum.juce.com/u/jamiebullock)\
**Post date:** [March 31, 2017, 4:14pm UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595/1 "2017-03-31T16:14:23Z")

</div>

Minimal reproducible example: if I place the following code at global scope, it crashes with the call stack shown (below).

`std::vector<var> foo = {0};`

The crash is here:

```
var::var (const var& valueToCopy) : type (valueToCopy.type)
{
    type->createCopy (value, valueToCopy.value);
}

```

Same problem for `std::map`. It’s fine if I initialise the vector inside `main()`. Is this a bug or have I misunderstood something?

Jamie

–

```
#0	0x000000010013d524 in juce::var::var(juce::var const&) at /Users/jamie/Desktop/NewProject/Builds/MacOSX/../../../../Documents/JUCE/modules/juce_core/containers/juce_Variant.cpp:449
#1	0x000000010013996d in juce::var::var(juce::var const&) at /Users/jamie/Desktop/NewProject/Builds/MacOSX/../../../../Documents/JUCE/modules/juce_core/containers/juce_Variant.cpp:448
#2	0x0000000100002078 in void std::__1::allocator<juce::var>::construct<juce::var, juce::var const&>(juce::var*, juce::var const&&&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1752
#3	0x0000000100002063 in void std:: __1::allocator_traits<std::__ 1::allocator<juce::var> >::__construct<juce::var, juce::var const&>(std::__1::integral_constant<bool, true>, std::__1::allocator<juce::var>&, juce::var*, juce::var const&&&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1668
#4	0x0000000100002043 in void std:: __1::allocator_traits<std::__ 1::allocator<juce::var> >::construct<juce::var, juce::var const&>(std::__1::allocator<juce::var>&, juce::var*, juce::var const&&&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1514
#5	0x0000000100002023 in void std:: __1::allocator_traits<std::__ 1::allocator<juce::var> >::__construct_range_forward<juce::var const*, juce::var*>(std::__1::allocator<juce::var>&, juce::var const*, juce::var const*, juce::var*&) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1598
#6	0x0000000100001fec in std:: __1::enable_if<__ is_forward_iterator<juce::var const*>::value, void>::type std:: __1::vector<juce::var, std::__ 1::allocator<juce::var> >::__construct_at_end<juce::var const*>(juce::var const*, juce::var const*, unsigned long) at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1024
#7	0x0000000100002543 in std:: __1::vector<juce::var, std::__ 1::allocator<juce::var> >::vector(std::initializer_list<juce::var>) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1285
#8	0x000000010000243e in std:: __1::vector<juce::var, std::__ 1::allocator<juce::var> >::vector(std::initializer_list<juce::var>) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1278
#9	0x0000000100002414 in ::__cxx_global_var_init.1() at /Users/jamie/Desktop/NewProject/Source/Main.cpp:19
#10	0x00000001000026be in _GLOBAL__sub_I_Main.cpp ()
```

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://forum.juce.com/u/jules)\
**Post date:** [March 31, 2017, 4:51pm UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595/2 "2017-03-31T16:51:04Z")

</div>

Yup, That’s because in C++ the order of initialisation of static variables is undefined, and var itself has some internal static variables which must have been created before it can be safely used.

So the take-home message is: Don’t use var (or any complex type, really!) in file-scope statics. You’re probably OK with them in function-scoped statics though.

---

<div class="post-metadata">

**Author:** ![LiamG](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/liamg/32/6844_2.png) [@LiamG](https://forum.juce.com/u/LiamG)\
**Post date:** [July 5, 2019, 5:30am UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595/3 "2019-07-05T05:30:44Z")

</div>

I’m glad I found this thread–I’ve been bashing my head against this problem for the past hour.

I have a static const member variable of `var`, like this:

```
class SomeClass
{
    static const std::vector<var> m_vars;
}

```

but the normal way of initializing it in global namespace is not working:

```
const std::vector<var> SomeClass::m_vars { var("text"), var(2.0f) };

```

What is the best solution? Should I just forego the `const` and initialize it on site? Or is there some other workaround?

---

<div class="post-metadata">

**Author:** ![jamiebullock](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jamiebullock/32/459_2.png) [@jamiebullock](https://forum.juce.com/u/jamiebullock)\
**Post date:** [July 5, 2019, 6:47am UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595/4 "2019-07-05T06:47:52Z")

</div>

This is known as the static initialisation order fiasco, and stems from initialisation order of static variables between compilation units being undefined. Putting the static at class scope as you have done won’t help because it doesn’t impose any further constraints on initialisation order. What you need to do is place the static inside a function (or method) as @jules suggested, therefore forcing the static to be initialised when the function is first called. This is sometimes called lazy initialisation.

So you could write:

```auto
class SomeClass
{
       const std::vector<var>& getVars()
       {
               static const std::vector<var> m_vars;
               return m_vars;
       }
}

```

Then access the static later with:

```auto
const auto& vars = SomeClass().getVars() // m_vars is initialised when getVars() is first called  

```

Further explanation can be found [here](https://isocpp.org/wiki/faq/ctors#static-init-order)

---

<div class="post-metadata">

**Author:** ![LiamG](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/liamg/32/6844_2.png) [@LiamG](https://forum.juce.com/u/LiamG)\
**Post date:** [July 5, 2019, 7:56am UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595/5 "2019-07-05T07:56:46Z")

</div>

Thanks for the link. I was already trying to further wrap the static in a class, but I hadn’t thought of wrapping it in a function.

My situation is a bit more complicated because I am actually trying to create an `std::shared_ptr` of type `var`. I didn’t bring this up in the last post because it didn’t seem relevant then, but it seems relevant now.

The behavior I’m trying to replicate is this:

```
class SomeClass
{
    static const std::shared_ptr<var> m_vars;
}

```

(Let’s forget about the `std::vector` for now, although it will be there in my final solution).

Using the _Construct on First Use Idiom_, I need to use a function to declare the static. Should that function return `static const std::make_shared` like this?

```
class SomeClass
{
       const std::shared_ptr<var>& getVars()
       { // vvv
               static const std::make_shared<var> m_vars (0.4f);
               return m_vars;
       }
}

```

Or should the function return a `std::shared_ptr` instead of `std::make_shared`? I didn’t know about static declarations inside functions until today, so I’m not yet able to picture how they will interact with the reference count inside `shared_ptr`.

Note: a `static std::shared_ptr` might seem like a dubious concoction to begin with, but I believe that it makes sense in the context I’m working in. I can elaborate if necessary.

---

<div class="post-metadata">

**Author:** ![anima](https://avatars.discourse-cdn.com/v4/letter/a/c67d28/32.png) [@anima](https://forum.juce.com/u/anima)\
**Post date:** [July 5, 2019, 9:47am UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595/6 "2019-07-05T09:47:28Z")

</div>

Maybe explain what you’re trying to achieve?

There is no point having a static shared\_ptr. In general, I’d avoid using static with any complex objects.

---

<div class="post-metadata">

**Author:** ![yfede](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/yfede/32/506_2.png) [@yfede](https://forum.juce.com/u/yfede)\
**Post date:** [July 5, 2019, 10:17am UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595/7 "2019-07-05T10:17:32Z")

</div>

> [@jamiebullock](#):
>
> So you could write:
> 
> ```auto
> class SomeClass
> {
> const std::vector<var>& getVars()
> {
> static const std::vector<var> m_vars;
> return m_vars;
> }
> }
> 
> ```

IIRC the method that returns the static instance can itself be static, saving you the need to create a temporary object just to call it, so your code becomes:

```auto
class SomeClass
{
public: // you can spare 'public' only if you declare this a struct instead of a class
       static const std::vector<var>& getVars()
       {
               static const std::vector<var> m_vars;
               return m_vars;
       }
}

```

and you access it via `SomeClass::getVars()`

---

<div class="post-metadata">

**Author:** ![LiamG](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/liamg/32/6844_2.png) [@LiamG](https://forum.juce.com/u/LiamG)\
**Post date:** [July 5, 2019, 10:40am UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595/8 "2019-07-05T10:40:09Z")

</div>

@Anima  
Yeah, I know it sounds a bit crazy. I suppose it’s good for me to take the time to spell this out in full, so that I can get feedback on whether the whole thing makes sense or not.

**Short version** : I’m actually not trying to create a static std::shared\_ptr, but rather trying to create a static object which has a shared\_ptr as an argument. This runs into the same problems as described above, which is why I simplified it a bit in the previous posts.

**Long version** : I have a functor class `CopyPropertiesFromVector` that I’m using to copy properties from an `std::vector` to a `ValueTree`. Now `CopyPropertiesFromVector` has a `std::shared_ptr` to another `CopyPropertiesFromVector` object, which it can fall back to if this one doesn’t work. The class is working really well, and I want to keep the `shared_ptr` functionality, as it gives me a lot of flexibility.

But there are some copy profiles that I’m using quite commonly, so I thought I’d make them static. So what I want to create is something like the following pseudo-code:

```
static const CopyPropertiesFromVector commonCopyProfile (vectorOfVars, std::make_shared<CopyPropertiesFromVector> (secondVector, nullptr)); 

```

That’s when I ran into these problems, since the `secondVector` argument is calling `vars` which haven’t been initialized yet.

I hope this makes sense, and would welcome feedback. I’m still hoping that there’s some trick that will allow me to make it static.

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [July 5, 2019, 10:45am UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595/9 "2019-07-05T10:45:09Z")

</div>

I think shared\_ptr is not what you want in this case. A shared\_ptr is a solution to share the ownership of an object between multiple objects or local references, that have an interest.

static variables have an undetermined lifetime, so the lifetime of the object in your shared\_ptr gets an undefined lifetime too, which is probably not what you want.

It sounds to me like you are after either a [singleton](https://docs.juce.com/develop/group __juce__ core-memory.html#gacd79c49d860c4386b12231ca141a41b9) or a [SharedResourcePointer](https://docs.juce.com/develop/classSharedResourcePointer.html). Could that be a cleaner alternative?

---

<div class="post-metadata">

**Author:** ![LiamG](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/liamg/32/6844_2.png) [@LiamG](https://forum.juce.com/u/LiamG)\
**Post date:** [July 5, 2019, 10:49am UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595/10 "2019-07-05T10:49:56Z")

</div>

The second time you’re telling me this 🙂

Could you explain the difference between `SharedResourcePointer` and `std::shared_ptr`?

---

<div class="post-metadata">

**Author:** ![daniel](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/daniel/32/790_2.png) [@daniel](https://forum.juce.com/u/daniel)\
**Post date:** [July 5, 2019, 10:58am UTC](https://forum.juce.com/t/using-a-variant-in-an-stl-container-initialised-at-global-scope-crashes/21595/11 "2019-07-05T10:58:30Z")

</div>

Ah yes, I remember 🙂

A SharedResourcePointer is basically a singleton, but it is created and destroyed on the fly. Every time you need an object of X just create a SharedResourcePointer and done. If there is already one, you get it. If not it is created. A good use case is the AudioFormatManager. You need it from time to time, but actually you don’t care if it’s there or not. You just don’t want to create it too often. So when your DAW restores a session, it needs it often, so there is a high chance, there is already one present, and it will use it. But later, when all your sounds are in memory, nobody needs it, so in a SharedResourcePointer, it will be removed, vs. a singleton would linger around until the program is closed (or it is manually removed).

A shared\_ptr is completely separate from these two, and has a totally different use case:  
Two objects have an interest in X. X shall be present, as long as one of the interested ones are alive.  
To allow that, the object X has a reference counter, it knows, how many people are looking at it. And if the last one switched off the telly, the object knows, it can go home, nobody is watching any longer.

The shared\_ptr is the same like juce’s ReferenceCountedObject with an implementation detail different, intrusive vs. non intrusive reference count, which probably doesn’t matter for you at the moment.
