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


#1

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 ()

#2

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.